OSS kalıcı birimleri (PV'ler) birden fazla istemciyi destekler ancak tam yazma desteği okuma performansını düşürür. Okuma/yazma ayrımı, okuma ve yazma işlemlerini ayrı bağlama yolları üzerinden yönlendirerek bu sorunu çözer. Model eğitimi, çıkarım ve veri analitiği gibi okuma yoğunluklu iş yüklerinde aktarım hızını artırır.
Bir MNIST el yazısı tanıma eğitimi işi üzerinden örneklendirilen ossfs veya OSS SDK ile OSS PV'leri için okuma/yazma ayrımını uygulayın.
Ön koşullar
Şunlara sahip olduğunuzdan emin olun:
En son Container Storage Interface (CSI) bileşeni yüklüdür. Farklı istemciler farklı CSI sürümleri gerektirir. Bkz. csi-plugin ve csi-provisioner bileşenlerini yönetme.
Kümeyle aynı Alibaba Cloud hesabında bulunan bir OSS paketi.
Hesaplar arası OSS erişimi önerilmez.
Bir istemci seçin
OSS PV'leri üç istemciyi destekler: ossfs 1,0, ossfs 2,0 ve strmvol. Her istemci salt okunur erişimi destekler; yazma yetenekleri ise farklılık gösterir:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bkz. İstemci seçimi referansı.
Kullanım senaryoları
Salt okunur erişim
Verilerin yanlışlıkla değiştirilmesini önlemek için PV erişim modunu ReadOnlyMany olarak ayarlayın. Bu ayar, çıkarım, veri analitiği ve günlük sorguları için uygundur.
Okuma ağırlıklı iş yükleri için ossfs 2,0 kullanın (CSI >= 1.33.1). Bkz. ossfs 2,0 PV'lerini kullanma.
Çok sayıda küçük dosya için strmvol kullanın. Bkz. strmvol PV'lerini kullanma.
ossfs 1,0'ı salt okunur senaryolar için optimize etmek üzere şu otherOpts parametrelerini yapılandırın. Çoğu iş yükü varsayılan değerleri kullanabilir.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Okuma/yazma erişimi
Veri yazan iş yükleri için PV erişim modunu ReadWriteMany olarak ayarlayın.
ossfs, eşzamanlı yazmalar için tutarlılığı garanti etmez. Aynı nesneler üzerinde birden fazla yazıcı olması veri bozulmasına neden olabilir. Kontrol noktası yazmaları için yol başına tek bir yazıcı kullanın.
Bağlanan yoldaki dosyaları silmek veya değiştirmek, OSS paketindeki nesneleri de siler veya değiştirir. Veri kaybını önlemek için sürüm oluşturmayı etkinleştirin.
Ayrı okuma ve yazma yollarına sahip okuma ağırlıklı iş yüklerinde (model eğitimi gibi), okuma yolunu önbellek etkinleştirilmiş şekilde ReadOnlyMany olarak bağlayın ve yazma işlemlerini bir ReadWriteMany PV'si veya OSS SDK aracılığıyla gerçekleştirin.
Okuma/yazma ayrımı nasıl çalışır?
Okuma/yazma ayrımı, okuma ve yazma işlemlerini aynı OSS paketinin farklı alt yollarına işaret eden ayrı bağlama noktaları üzerinden yönlendirir. Bu yaklaşım, okuma G/Ç işlemlerini yazma G/Ç işlemlerinden izole eder.
Okuma yolu — Bir alt yolu (örneğin,
/tf-train/train/data) önbellek etkinleştirilmişReadOnlyManyolarak bağlayın. Tekrarlanan okumalar bellekten karşılanır.Yazma yolu — Farklı bir alt yolu (örneğin,
/tf-train/training_logs)ReadWriteManyolarak bağlayın veya doğrudan SDK aracılığıyla yazın.
Örnek: MNIST el yazısı tanıma eğitimi
Eğitim işi şunları yapar:
Salt okunur bir PV kullanarak OSS paketindeki
/tf-train/train/datakonumundan eğitim veri kümesini okur.Bir okuma/yazma PV'si veya OSS SDK kullanarak eğitim kontrol noktalarını
/tf-train/training_logskonumuna yazar.
MNIST veri kümesini indirin ve OSS paketinizdeki /tf-train/train/data konumuna yükleyin:
OSS paketindeki dosya düzeni:

ossfs kullanarak okuma/yazma işlemlerini uygulama
Kontrol noktası yazmaları sıralı eklemeler olduğundan, hem ossfs 1,0 hem de ossfs 2,0 yazma yolu için kullanılabilir.
-
Eğitim uygulamasını dağıtın. Uygulama, OSS paketinin
/tf-trainalt yolunu pod'un/mntdizinine bağlar. Bkz. ossfs 1,0 statik olarak sağlanan birimleri kullanma veya ossfs 2,0 PV'lerini kullanma.-
Bir ossfs 1,0 PV'si oluşturun:
cat << EOF | kubectl apply -f - apiVersion: v1 kind: Secret metadata: name: oss-secret namespace: default stringData: akId: "<your-accesskey-id>" akSecret: "<your-accesskey-secret>" --- apiVersion: v1 kind: PersistentVolume metadata: name: tf-train-pv labels: alicloud-pvname: tf-train-pv spec: capacity: storage: 10Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain csi: driver: ossplugin.csi.alibabacloud.com volumeHandle: tf-train-pv nodePublishSecretRef: name: oss-secret namespace: default volumeAttributes: bucket: "<your-bucket-name>" url: "oss-<region>.aliyuncs.com" otherOpts: "-o max_stat_cache_size=0 -o allow_other" path: "/tf-train" --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: tf-train-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi selector: matchLabels: alicloud-pvname: tf-train-pv EOF -
Eğitim pod'unu oluşturun:
Eğitim sırasında, ossfs dosyaları
/mnt/training_logs(pod) konumundan/tf-train/training_logs(OSS paketi) konumuna yükler.cat << EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: labels: app: tfjob name: tf-mnist namespace: default spec: containers: - command: - sh - -c - python /app/main.py env: - name: NVIDIA_VISIBLE_DEVICES value: void - name: gpus value: "0" - name: workers value: "1" - name: TEST_TMPDIR value: "/mnt" image: registry.cn-beijing.aliyuncs.com/tool-sys/tf-train-demo:rw imagePullPolicy: Always name: tensorflow ports: - containerPort: 20000 name: tfjob-port protocol: TCP volumeMounts: - name: train mountPath: "/mnt" workingDir: /root priority: 0 restartPolicy: Never securityContext: {} terminationGracePeriodSeconds: 30 volumes: - name: train persistentVolumeClaim: claimName: tf-train-pvc EOF
-
-
Veri okuma ve yazma işlemlerini doğrulayın.
-
Pod durumunu kontrol edin:
kubectl get pod tf-mnistDurumun
RunningdeğerindenCompleteddeğerine değişmesini bekleyin:NAME READY STATUS RESTARTS AGE tf-mnist 0/1 Completed 0 2m12s -
Veri yükleme süresini kontrol edin:
kubectl logs tf-mnist | grep dataloadBeklenen çıktı:
dataload cost time: 1.54191803932 OSS Yönetim Konsolu üzerinde oturum açın ve paketteki
/tf-train/training_logsaltında dosyaların bulunduğunu doğrulayın.
-
Okuma/yazma ayrımı kullanarak okuma performansını optimize etme
Tek bir okuma/yazma PV'sini ikiye ayırın: veri kümesi için önbellek ayarı yapılmış salt okunur bir PV ve kontrol noktaları için bir yazma PV'si. Sadece bağlama yapılandırması değişir; eğitim kodu aynı kalır.
İki yazma seçeneği mevcuttur:
Seçenek 1: Kontrol noktası yazmaları için ayrı bir okuma/yazma ossfs PV'si kullanın.
Seçenek 2: ossfs'i tamamen atlayarak kontrol noktalarını doğrudan OSS SDK ile yazın.
Seçenek 1: Okuma/yazma ossfs PV'si kullanarak yazma
-
Veri kümesi için salt okunur bir ossfs 1,0 PV'si oluşturun. Temel yapılandırma değişiklikleri şunlardır:
Hem PV hem de PVC üzerinde
accessModesdeğeriniReadOnlyManyolarak ayarlayın. Veri kümesi alt yolunu/tf-train/train/dataolarak bağlayın.-
otherOptsiçine-o kernel_cache -o max_stat_cache_size=10000 -o umask=022ekleyin:kernel_cachebellek içi okuma önbelleğini etkinleştirir.max_stat_cache_size=1000010.000 meta veri girdisini (~40 MB) önbelleğe alır. Örnek türüne ve veri kümesi boyutuna göre ayarlayın.umask=022root olmayan kapsayıcı işlemlerine okuma erişimi sağlar.
cat << EOF | kubectl apply -f - apiVersion: v1 kind: Secret metadata: name: oss-secret namespace: default stringData: akId: "<your-accesskey-id>" akSecret: "<your-accesskey-secret>" --- apiVersion: v1 kind: PersistentVolume metadata: name: tf-train-pv labels: alicloud-pvname: tf-train-pv spec: capacity: storage: 10Gi accessModes: - ReadOnlyMany persistentVolumeReclaimPolicy: Retain csi: driver: ossplugin.csi.alibabacloud.com volumeHandle: tf-train-pv nodePublishSecretRef: name: oss-secret namespace: default volumeAttributes: bucket: "<your-bucket-name>" url: "oss-<region>.aliyuncs.com" otherOpts: "-o kernel_cache -o max_stat_cache_size=10000 -o umask=022 -o allow_other" path: "/tf-train/train/data" --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: tf-train-pvc spec: accessModes: - ReadOnlyMany resources: requests: storage: 10Gi selector: matchLabels: alicloud-pvname: tf-train-pv EOF -
Kontrol noktaları için
/tf-train/training_logsalt yolunu bağlayan bir okuma/yazma ossfs 1,0 PV'si oluşturun. Sıralı kontrol noktası yazmaları önbellekten yararlanmadığı için meta veri önbelleğe alma devre dışı bırakılır (max_stat_cache_size=0).cat << EOF | kubectl apply -f - apiVersion: v1 kind: PersistentVolume metadata: name: tf-logging-pv labels: alicloud-pvname: tf-logging-pv spec: capacity: storage: 10Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain csi: driver: ossplugin.csi.alibabacloud.com volumeHandle: tf-logging-pv nodePublishSecretRef: name: oss-secret namespace: default volumeAttributes: bucket: "<your-bucket-name>" url: "oss-<region>.aliyuncs.com" otherOpts: "-o max_stat_cache_size=0 -o allow_other" path: "/tf-train/training_logs" --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: tf-logging-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi selector: matchLabels: alicloud-pvname: tf-logging-pv EOF -
Her iki PV'yi de bağlanmış olarak eğitim pod'unu dağıtın.
Kod değişikliği gerekmez. Her iki PV'yi de bağlayın: salt okunur PV'yi
/mnt/train/datakonumuna ve okuma/yazma PV'sini/mnt/training_logskonumuna bağlayın.cat << EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: labels: app: tfjob name: tf-mnist namespace: default spec: containers: - command: - sh - -c - python /app/main.py env: - name: NVIDIA_VISIBLE_DEVICES value: void - name: gpus value: "0" - name: workers value: "1" - name: TEST_TMPDIR value: "/mnt" image: registry.cn-beijing.aliyuncs.com/tool-sys/tf-train-demo:rw imagePullPolicy: Always name: tensorflow ports: - containerPort: 20000 name: tfjob-port protocol: TCP volumeMounts: - name: train mountPath: "/mnt/train/data" - name: logging mountPath: "/mnt/training_logs" workingDir: /root priority: 0 restartPolicy: Never securityContext: {} terminationGracePeriodSeconds: 30 volumes: - name: train persistentVolumeClaim: claimName: tf-train-pvc - name: logging persistentVolumeClaim: claimName: tf-logging-pvc EOF
Seçenek 2: OSS SDK kullanarak yazma
Kontrol noktalarını doğrudan SDK ile OSS'e yazın; okuma/yazma PV'sine gerek yoktur. Pod, salt okunur bir PV'den okur ve SDK aracılığıyla yazar.
-
Kapsayıcı görüntüsüne OSS Python SDK'yı ekleyin:
RUN pip install oss2Bkz. Kurulum.
-
Kontrol noktalarını SDK kullanarak yüklemek için eğitim kodunu değiştirin. Orijinal kod, her 100 yinelemede
tf.train.Savervemax_to_keep=0kullanarak kontrol noktalarınılog_dirkonumuna kaydeder ve 1.000 yineleme sonunda 10 kontrol noktası seti üretir.Bellek kullanımını azaltmak için yalnızca en son kontrol noktasını saklamak üzere
max_to_keep=1olarak ayarlayın.Kaydettikten sonra her kontrol noktasını
put_object_from_fileile OSS'e yükleyin.
Okuma ve yazma yolları ayrıldığında aktarım hızını daha da artırmak için SDK ile asenkron G/Ç kullanın.
def train(): ... saver = tf.train.Saver(max_to_keep=0) for i in range(FLAGS.max_steps): if i % 10 == 0: # Record summaries and test-set accuracy summary, acc = sess.run([merged, accuracy], feed_dict=feed_dict(False)) print('Accuracy at step %s: %s' % (i, acc)) if i % 100 == 0: print('Save checkpoint at step %s: %s' % (i, acc)) saver.save(sess, FLAGS.log_dir + '/model.ckpt', global_step=i)SDK tabanlı yüklemelerle değiştirin. İki değişiklik bellek kullanımını azaltır ve okuma/yazma PV'sini ortadan kaldırır: AccessKey ve paket ayarlarını ortam değişkenlerinden okuyun. Bkz. Erişim kimlik bilgilerini yapılandırma.
import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider()) url = os.getenv('URL','<default-url>') bucketname = os.getenv('BUCKET','<default-bucket-name>') bucket = oss2.Bucket(auth, url, bucketname) ... def train(): ... saver = tf.train.Saver(max_to_keep=1) for i in range(FLAGS.max_steps): if i % 10 == 0: # Record summaries and test-set accuracy summary, acc = sess.run([merged, accuracy], feed_dict=feed_dict(False)) print('Accuracy at step %s: %s' % (i, acc)) if i % 100 == 0: print('Save checkpoint at step %s: %s' % (i, acc)) saver.save(sess, FLAGS.log_dir + '/model.ckpt', global_step=i) # FLAGS.log_dir = os.path.join(os.getenv('TEST_TMPDIR', '/mnt'),'training_logs') for path,_,file_list in os.walk(FLAGS.log_dir) : for file_name in file_list: bucket.put_object_from_file(os.path.join('tf-train/training_logs', file_name), os.path.join(path, file_name))Değiştirilen kapsayıcı görüntüsü
registry.cn-beijing.aliyuncs.com/tool-sys/tf-train-demo:roşeklindedir. -
Pod'u salt okunur PV ve SDK kimlik bilgileriyle dağıtın. Pod,
accessModesdeğeriniReadOnlyManyolarak ayarlar ve SDK'nın PV ile aynı kimlik bilgileriyle kimlik doğrulaması yapabilmesi içinOSS_ACCESS_KEY_IDveOSS_ACCESS_KEY_SECRETdeğerlerini iletir.cat << EOF | kubectl apply -f - apiVersion: v1 kind: Secret metadata: name: oss-secret namespace: default stringData: akId: "<your-accesskey-id>" akSecret: "<your-accesskey-secret>" --- apiVersion: v1 kind: PersistentVolume metadata: name: tf-train-pv labels: alicloud-pvname: tf-train-pv spec: capacity: storage: 10Gi accessModes: - ReadOnlyMany persistentVolumeReclaimPolicy: Retain csi: driver: ossplugin.csi.alibabacloud.com volumeHandle: tf-train-pv nodePublishSecretRef: name: oss-secret namespace: default volumeAttributes: bucket: "<your-bucket-name>" url: "oss-<region>.aliyuncs.com" otherOpts: "-o kernel_cache -o max_stat_cache_size=10000 -o umask=022 -o allow_other" path: "/tf-train/train/data" --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: tf-train-pvc spec: accessModes: - ReadOnlyMany resources: requests: storage: 10Gi selector: matchLabels: alicloud-pvname: tf-train-pv --- apiVersion: v1 kind: Pod metadata: labels: app: tfjob name: tf-mnist namespace: default spec: containers: - command: - sh - -c - python /app/main.py env: - name: NVIDIA_VISIBLE_DEVICES value: void - name: gpus value: "0" - name: workers value: "1" - name: TEST_TMPDIR value: "/mnt" - name: OSS_ACCESS_KEY_ID #The source of the AccessKey is the same as that of the PV. valueFrom: secretKeyRef: name: oss-secret key: akId - name: OSS_ACCESS_KEY_SECRET #The source of the AccessKey is the same as that of the PV. valueFrom: secretKeyRef: name: oss-secret key: akSecret - name: URL #You can ignore this if a default URL is configured. value: "https://oss-<region>.aliyuncs.com" - name: BUCKET #You can ignore this if a default BUCKET is configured. value: "<bucket-name>" image: registry.cn-beijing.aliyuncs.com/tool-sys/tf-train-demo:ro imagePullPolicy: Always name: tensorflow ports: - containerPort: 20000 name: tfjob-port protocol: TCP volumeMounts: - name: train mountPath: "/mnt/train/data" workingDir: /root priority: 0 restartPolicy: Never securityContext: {} terminationGracePeriodSeconds: 30 volumes: - name: train persistentVolumeClaim: claimName: tf-train-pvc EOF
Okuma/yazma ayrımını doğrulama
Herhangi bir yazma seçeneğiyle dağıtım yaptıktan sonra:
-
Pod durumunu kontrol edin:
kubectl get pod tf-mnistDurumun
Completedolarak değişmesini bekleyin:NAME READY STATUS RESTARTS AGE tf-mnist 0/1 Completed 0 2m25s -
Veri yükleme süresini kontrol edin:
kubectl logs tf-mnist | grep dataloadOkuma/yazma ayrımı ve kernel önbelleği etkinleştirildiğinde veri yükleme süresi azalır:
dataload cost time: 0.843528985977Ayrım olmadan temel çizgi yaklaşık 1,54 saniyedir. Daha büyük eğitim işleri ve tekrarlanan veri yüklemeleri daha yüksek iyileşme gösterir.
-
OSS Yönetim Konsolu üzerinde oturum açın ve paketteki
/tf-train/training_logsaltında kontrol noktası dosyalarının bulunduğunu doğrulayın.
Referanslar
OSS SDK referansı
Bu konuda Python SDK kullanılmıştır. Kullanılabilen diğer SDK'lar şunlardır:
Diğer SDK'lar (PHP, Node.js, Browser.js, .NET, Android, iOS, Ruby) için bkz. SDK Referansı.
Diğer yazma araçları
Bu araçlar da OSS'e yazmayı destekler:
|
|
|
|
|
|
|
|
|
|
|