Tüm Ürünler
Search
Belge Merkezi

Container Service for Kubernetes:Best practices for OSS read/write splitting

Son Güncelleme:Oct 06, 2026

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:

Önemli

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:


İstemci


Salt okunur


Okuma/yazma


En uygun olduğu durum


ossfs 1,0


Evet


Tam yazma


Genel okuma/yazma iş yükleri; doğrudan okuma modu mevcuttur (v1.91+)


ossfs 2,0


Evet


Yalnızca sıralı ekleme yazmaları


Okuma ağırlıklı iş yükleri; CSI >= 1.33.1 gerekir


strmvol


Evet


—


Çok sayıda küçük dosya (veri kümeleri, zaman serisi günlükleri, niceliksel geriye dönük testler)

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.

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.


Parametre


Varsayılan


Açıklama


kernel_cache


Devre dışı


Gerçek zamanlı olmayan okumalar için kernel arabellek önbelleğini etkinleştirir. Önbelleğe alma için boş belleği kullanır.


parallel_count


20


Büyük dosya yükleme ve indirme işlemleri için eşzamanlı parçalar.


max_multireq


20


Maksimum eşzamanlı meta veri listeleme isteği sayısı. parallel_count değerinden büyük veya ona eşit olmalıdır.


max_stat_cache_size


1000


Önbelleğe alınan meta veri girdilerinin sayısı. Devre dışı bırakmak için 0 olarak ayarlayın. Büyük dizinlerde ls komutunun hızını artırmak için bu değeri artırın; 10.000 girdi yaklaşık 40 MB yer kaplar.


direct_read


Devre dışı


Salt okunur senaryolar için doğrudan okuma modu (ossfs >= 1.91). Bkz. Yeni ossfs 1,0 sürümünün özellikleri ve performans testi ve Salt okunur senaryolar için performans optimizasyonu.

Okuma/yazma erişimi

Veri yazan iş yükleri için PV erişim modunu ReadWriteMany olarak ayarlayın.

Not

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.

Uyarı

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ş ReadOnlyMany olarak bağlayın. Tekrarlanan okumalar bellekten karşılanır.

  • Yazma yolu — Farklı bir alt yolu (örneğin, /tf-train/training_logs) ReadWriteMany olarak 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:

  1. Salt okunur bir PV kullanarak OSS paketindeki /tf-train/train/data konumundan eğitim veri kümesini okur.

  2. Bir okuma/yazma PV'si veya OSS SDK kullanarak eğitim kontrol noktalarını /tf-train/training_logs konumuna yazar.

MNIST veri kümesini indirin ve OSS paketinizdeki /tf-train/train/data konumuna yükleyin:

OSS paketindeki dosya düzeni:

oss-read-write-splitting-1

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.

  1. Eğitim uygulamasını dağıtın. Uygulama, OSS paketinin /tf-train alt yolunu pod'un /mnt dizinine bağlar. Bkz. ossfs 1,0 statik olarak sağlanan birimleri kullanma veya ossfs 2,0 PV'lerini kullanma.

    1. 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
    2. 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
  2. Veri okuma ve yazma işlemlerini doğrulayın.

    1. Pod durumunu kontrol edin:

      kubectl get pod tf-mnist

      Durumun Running değerinden Completed değerine değişmesini bekleyin:

      NAME       READY   STATUS      RESTARTS   AGE
      tf-mnist   0/1     Completed   0          2m12s
    2. Veri yükleme süresini kontrol edin:

      kubectl logs tf-mnist | grep dataload

      Beklenen çıktı:

      dataload cost time:  1.54191803932
    3. OSS Yönetim Konsolu üzerinde oturum açın ve paketteki /tf-train/training_logs altı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

  1. 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 accessModes değerini ReadOnlyMany olarak ayarlayın. Veri kümesi alt yolunu /tf-train/train/data olarak bağlayın.

    • otherOpts içine -o kernel_cache -o max_stat_cache_size=10000 -o umask=022 ekleyin:

      • kernel_cache bellek içi okuma önbelleğini etkinleştirir.

      • max_stat_cache_size=10000 10.000 meta veri girdisini (~40 MB) önbelleğe alır. Örnek türüne ve veri kümesi boyutuna göre ayarlayın.

      • umask=022 root 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
  2. Kontrol noktaları için /tf-train/training_logs alt 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
  3. 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/data konumuna ve okuma/yazma PV'sini /mnt/training_logs konumuna 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.

  1. Kapsayıcı görüntüsüne OSS Python SDK'yı ekleyin:

    RUN pip install oss2

    Bkz. Kurulum.

  2. Kontrol noktalarını SDK kullanarak yüklemek için eğitim kodunu değiştirin. Orijinal kod, her 100 yinelemede tf.train.Saver ve max_to_keep=0 kullanarak kontrol noktalarını log_dir konumuna 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=1 olarak ayarlayın.

    • Kaydettikten sonra her kontrol noktasını put_object_from_file ile 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.

  3. Pod'u salt okunur PV ve SDK kimlik bilgileriyle dağıtın. Pod, accessModes değerini ReadOnlyMany olarak ayarlar ve SDK'nın PV ile aynı kimlik bilgileriyle kimlik doğrulaması yapabilmesi için OSS_ACCESS_KEY_ID ve OSS_ACCESS_KEY_SECRET değ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:

  1. Pod durumunu kontrol edin:

    kubectl get pod tf-mnist

    Durumun Completed olarak değişmesini bekleyin:

    NAME       READY   STATUS      RESTARTS   AGE
    tf-mnist   0/1     Completed   0          2m25s
  2. Veri yükleme süresini kontrol edin:

    kubectl logs tf-mnist | grep dataload

    Okuma/yazma ayrımı ve kernel önbelleği etkinleştirildiğinde veri yükleme süresi azalır:

    dataload cost time:  0.843528985977

    Ayrı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.

  3. OSS Yönetim Konsolu üzerinde oturum açın ve paketteki /tf-train/training_logs altında kontrol noktası dosyalarının bulunduğunu doğrulayın.

    image.png

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:


Araç


Referans


OSS Yönetim Konsolu


Hızlı başlangıç


OpenAPI


PutObject


ossutil komut satırı arabirimi


cp (dosya yükleme)


ossbrowser grafiksel yönetim aracı


Yaygın işlemler