Çoklu NUMA mimarisine sahip örneklerde, aynı düğüm üzerinde çalışan iş yükleri yerel belleği tüketerek uygulamanızın bellek sayfalarını uzak NUMA düğümlerine itebilir. QuickPath Interconnect (QPI) veri yolu üzerinden gerçekleşen düğümler arası erişim, yerel erişime kıyasla daha yavaştır; bu durum aktarım hızını düşürür ve gecikme süresini artırır. ack-koordinator'un yakındaki bellek erişimi hızlandırma özelliği, çalışma zamanında uzak bellek sayfalarını tespit eder ve çalışan hizmetleri kesintiye uğratmadan bunları yerel NUMA düğümüne geri taşır.
Ön koşullar
Başlamadan önce aşağıdakilere sahip olduğunuzdan emin olun:
Kubernetes 1.18 veya sonraki bir sürümü çalıştıran bir ACK Pro kümesi. Daha fazla bilgi için bkz. ACK yönetilen kümesi oluşturma.
Kümeyle bağlantı kurmuş bir kubectl istemcisi. Daha fazla bilgi için bkz. Kümenin kubeconfig dosyasını alma ve kubectl ile kümeye bağlanma.
-
ack-koordinator (eski adıyla ack-slo-manager) 1.2.0-ack1.2 veya sonraki bir sürümün yüklü olması. Daha fazla bilgi için bkz. ack-koordinator (eski adıyla ack-slo-manager).
Notack-koordinator, resource-controller'daki tüm özellikleri içerir. Şu anda resource-controller kullanıyorsanız, ack-koordinator'u yüklemeden önce bunu kaldırın. Daha fazla bilgi için bkz. resource-controller'ı kaldırma.
-
ecs.ebmc, ecs.ebmg, ecs.ebmgn, ecs.ebmr, ecs.ebmhfc veya ecs.scc örnek ailelerinden 5., 6., 7. veya 8. nesil Elastic Compute Service (ECS) örnekleri ve bunların çoklu NUMA örnekleri olarak dağıtılmış olması.
NotÖzellik, ecs.ebmc8i.48xlarge, ecs.c8i.32xlarge ve ecs.g8i.48xlarge türlerindeki 8. nesil ECS örneklerinde en iyi performansı gösterir. Daha fazla bilgi için bkz. ECS örnek aileleri.
Topoloji duyarlı CPU zamanlaması kullanılarak CPU çekirdeklerinin bağlandığı, çoklu NUMA örnekleri üzerinde dağıtılan uygulamalar. Daha fazla bilgi için bkz. Topoloji duyarlı CPU zamanlamasını etkinleştirme.
Faturalama
ack-koordinator'u yüklemek veya kullanmak için ücret alınmaz. Ancak aşağıdaki senaryolarda ücretlendirme söz konusu olabilir:
ack-koordinator, kurulduktan sonra worker düğüm kaynaklarını tüketen yönetilmeyen bir bileşendir. Kurulum sırasında her modülün talep edeceği kaynak miktarını belirtebilirsiniz.
Varsayılan olarak ack-koordinator, izleme ölçümlerini (kaynak profilleme ve ayrıntılı zamanlama ölçümleri gibi) Prometheus ölçümleri olarak sunar. ack-koordinator için Prometheus ölçümlerini etkinleştirir ve Managed Service for Prometheus kullanırsanız, bu ölçümler özel ölçümler olarak sayılır ve ücretlendirilir. Etkinleştirmeden önce ücretsiz kota ve faturalama kurallarını anlamak için Managed Service for Prometheus'a ait Faturalama konusunu okuyun. Daha fazla bilgi için bkz. Gözlemlenebilir veri miktarını ve faturaları sorgulama.
Nasıl çalışır?
Çoklu NUMA mimarisinde, bir NUMA düğümünün sanal çekirdeğinde çalışan işlemlerin uzak bir NUMA düğümündeki belleğe erişmesi gerekebilir. Bu tür düğümler arası erişim QPI veri yolu üzerinden gerçekleşir ve yerel bellek erişimine göre daha uzun sürer. Yüksek bellek yükü altında—örneğin, aynı NUMA düğümündeki birlikte çalışan iş yükleri yerel belleği tükettiğinde—bir uygulamanın bellek sayfaları uzak bir NUMA düğümüne itilebilir. Bu durum yerel bellek isabet oranını düşürür ve performansı olumsuz etkiler.
ack-koordinator, bu çalışma zamanı bellek kaymasını giderir. Bir pod için bellek yerelliği etkinleştirildiğinde, her düğümdeki koordlet aracısı, pod'un hangi bellek sayfalarının uzak NUMA düğümlerinde bulunduğunu tespit eder ve bunları yerel düğüme taşır. Taşıma işlemi güvenlidir; pod'un yeniden başlatılmasını veya trafiğin kesilmesini gerektirmez.
Redis çalıştıran bir ecs.ebmc8i.48xlarge örneği üzerinde yapılan kıyaslamalar, tamamen yerel bellek kullanımının, rastgele dağıtılmış belleğe göre %10,52 daha yüksek QPS ve tamamen uzak belleğe göre %26,12 daha yüksek QPS sağladığını göstermektedir.
Kıyaslama sonuçları teoriktir. Gerçek sonuçlar ortama göre değişiklik gösterir.

Kullanım senaryoları
Yakındaki bellek erişimi hızlandırma özelliği aşağıdakiler için uygundur:
Bellek yoğunluklu iş yükleri — Büyük ölçekli Redis in-memory veritabanları ve bellek erişimi gecikmesinin doğrudan aktarım hızını etkilediği benzeri iş yükleri.
DSA destekli ECS örnekleri — Intel Data Streaming Accelerator (DSA) ile entegre edilmiş ECS örnekleri, özellik performansını iyileştirebilir ve CPU tüketimini azaltabilir.
Sınırlamalar
Örnek NUMA olmayan bir mimari kullanıyorsa veya işlem tüm NUMA düğümlerinde çalışıyorsa özellik atlanır. Her iki durumda da taşıma yapılacak bir uzak NUMA düğümü bulunmaz.
Taşıma sırasında bir işlem sonlandırılırsa, ilgili işlemin taşıması başarısız olur. ack-koordinator, başarısız olan işlem kimliğini pod olayına kaydeder ve diğer işlemlerin taşınmasına devam eder.
Periyodik hızlandırma kullanılırken (
migrateIntervalMinutes > 0), yerel bellek oranındaki değişim veya hızlandırma sonucu %10'u aştığında yalnızca bir olay kaydedilir.
Yakındaki bellek erişimi hızlandırmayı etkinleştirin
Adım 1: Özelliği etkinleştirin
İki yöntem kullanılabilir. Tek tek pod'ları hedeflemek için açıklama (annotation) yöntemini veya belirli bir hizmet kalitesi (QoS) sınıfındaki tüm pod'lara ayarı uygulamak için ConfigMap yöntemini kullanabilirsiniz.
Tek bir pod için etkinleştirme
Bir pod için yakındaki bellek erişimi hızlandırmayı etkinleştirmek üzere aşağıdaki komutu çalıştırın:
kubectl annotate pod <pod-name> koordinator.sh/memoryLocality='{"policy": "bestEffort"}' --overwrite
policy parametresi aşağıdaki değerleri kabul eder:
| Değer | Davranış |
|---|---|
bestEffort |
Bellek sayfalarını uzak NUMA düğümlerinden yerel NUMA düğümüne anında taşımaya tetikler |
none |
Yakındaki bellek erişimi hızlandırmayı devre dışı bırakır |
Belirli bir QoS sınıfındaki tüm pod'lar için etkinleştirme
-
Aşağıdaki içeriğe sahip
ml-config.yamladlı bir dosya oluşturun:apiVersion: v1 data: resource-qos-config: |- { "clusterStrategy": { "lsClass": { "memoryLocality": { "policy": "bestEffort" } } } } kind: ConfigMap metadata: name: ack-slo-config namespace: kube-system -
kube-system ad alanında
ack-slo-configConfigMap'inin zaten var olup olmadığını kontrol edin:kubectl get cm ack-slo-config -n kube-system-
ConfigMap yoksa oluşturun:
kubectl apply -f ml-config.yaml -
ConfigMap zaten varsa, mevcut QoS ayarlarının üzerine yazılmaması için yamalayın:
kubectl patch cm -n kube-system ack-slo-config --patch "$(cat ml-config.yaml)"
-
Adım 2: Özelliği doğrulayın
Pod olaylarını kontrol etmek için aşağıdaki komutu çalıştırın:
kubectl describe pod <pod-name>
Aşağıdaki tabloda beklenen olay türleri ve anlamları açıklanmaktadır:
| Olay türü | Örnek mesaj | Anlamı |
|---|---|---|
MemoryLocalityCompleted |
Container <name> completed: migrated memory from remote numa: 1 to local numa: 0 ... Total: 2 container(s) completed, 0 failed, 0 skipped; cur local memory ratio 100, rest remote memory pages 0 |
Taşıma başarılı oldu. Olay, her konteyner için taşıma yönünü ve elde edilen yerel bellek oranını kaydeder. |
MemoryLocalityCompleted (başarısızlıkla) |
failed to migrate the following processes: failed pid: 111111, error: No such process, from remote numa: 0 to local numa: 1 |
Taşıma sırasında bir veya daha fazla işlem sonlandırıldı. Olay, başarısız olan her işlemin PID'sini kaydeder. Kalan konteynerler başarıyla taşındı. |
MemoryLocalitySkipped |
no target numa |
Uzak NUMA düğümü bulunamadı. Bu durum, NUMA olmayan örneklerde veya işlem tüm NUMA düğümlerinde çalıştığında ortaya çıkar. Herhangi bir işlem gerekmez. |
MemoryLocalityFailed |
Hata mesajı değişir | Beklenmeyen bir hata oluştu. Ayrıntılar için hata mesajını kontrol edin. |
Adım 3 (İsteğe bağlı): Periyodik hızlandırmayı ayarlayın
Varsayılan olarak açıklama tek bir taşıma işlemini tetikler. Taşıma işlemlerini bir zamanlamaya göre tekrarlamak için migrateIntervalMinutes parametresini ekleyin.
Yinelenen bir aralık ayarlamadan önce en son taşıma işleminin tamamlandığından emin olun. Yerel bellek oranı veya hızlandırma sonucu %10'dan fazla değiştiğinde yalnızca bir olay kaydedilir.
kubectl annotate pod <pod-name> koordinator.sh/memoryLocality='{"policy": "bestEffort","migrateIntervalMinutes":10}' --overwrite
migrateIntervalMinutes parametresi, taşıma işlemleri arasındaki minimum aralığı dakika cinsinden belirtir:
| Değer | Davranış |
|---|---|
0 |
Tek bir anında taşıma işlemi tetikler (parametreyi atlamakla aynıdır) |
> 0 |
Anında bir taşıma işlemi tetikler, ardından belirtilen aralıkla tekrarlar |
none |
Yakındaki bellek erişimi hızlandırma özelliğini devre dışı bırakır |
Kıyaslama: Redis üzerindeki performans etkisi
Bu bölümde ecs.ebmc8i.48xlarge ve ecs.ebmg7a.64xlarge örnek türlerine ait kıyaslama sonuçları açıklanmaktadır.
Sonuçlar stres testi aracına ve ortama bağlıdır. Aşağıdaki sonuçlar yalnızca bu iki örnek türü için geçerlidir.
Test ortamı
Test edilen makineler: Redis uygulaması çalıştıran ecs.ebmc8i.48xlarge ve ecs.ebmg7a.64xlarge örnekleri
Redis uygulaması: Çoklu iş parçacıklı, 4 sanal çekirdek, 32 GB bellek (görüntü:
redis:6.0.5)-
Stres testi makinesi: Test edilen makineye istek gönderen ayrı bir makine
NotDaha düşük teknik özelliklere sahip test makineleri için tek iş parçacıklı bir Redis örneği dağıtın ve CPU ile bellek isteklerini buna göre azaltın.
Test prosedürü

-
Aşağıdaki YAML kullanarak bir Redis uygulaması dağıtın. Test makinenizin teknik özellikleriyle eşleşecek şekilde
redis-configdeğerini ayarlayın.--- kind: ConfigMap apiVersion: v1 metadata: name: example-redis-config data: redis-config: | maxmemory 32G maxmemory-policy allkeys-lru io-threads-do-reads yes io-threads 4 --- kind: Service apiVersion: v1 metadata: name: redis spec: type: NodePort ports: - port: 6379 targetPort: 6379 nodePort: 32379 selector: app: redis --- apiVersion: v1 kind: Pod metadata: name: redis annotations: cpuset-scheduler: "true" # Bind vCores using topology-aware CPU scheduling labels: app: redis spec: containers: - name: redis image: redis:6.0.5 command: ["bash", "-c", "redis-server /redis-master/redis.conf"] ports: - containerPort: 6379 resources: limits: cpu: "4" # Adjust based on test machine specifications volumeMounts: - mountPath: /redis-master-data name: data - mountPath: /redis-master name: config volumes: - name: data emptyDir: {} - name: config configMap: name: example-redis-config items: - key: redis-config path: redis.conf -
Uzak NUMA bellek kaymasını simüle etmek için bellek yükünü artırın.
-
Aşağıdaki kabuk betiğini kullanarak Redis'e iş verisi yazın. Betik, verileri ardışık düzenler (pipelines) aracılığıyla toplu iş olarak yazar.
<max-out-cir>ve<max-in-cir>değerlerini kurulumunuz için uygun değerlerle değiştirin. 4 sanal çekirdekli, 32 GB'lık bir Redis örneği içinmax-out-cir=300vemax-in-cir=1000000kullanın.NotBüyük hacimli veri yazmak zaman alır. Yazma hızını en üst düzeye çıkarmak için betiği test edilen makinede çalıştırın.
for((j=1;j<=<max-out-cir>;j++)) do echo "set k$j-0 v$j-0" > data.txt for((i=1;i<=<max-in-cir>;i++)) do echo "set k$j-$i v$j-$i" >> data.txt done echo "$j" unix2dos data.txt # Pipeline writes require DOS format cat data.txt | redis-cli --pipe -h <redis-server-IP> -p <redis-server-port> doneVeri yazılırken, bellek kaymasını simüle etmek için aynı NUMA düğümündeki birlikte çalışan iş yüklerinin bellek yükünü artırın. İş yüklerini belirli bir NUMA düğümüne bağlamak için
numactl --membindkullanın. -
Bellek baskısını artırmak için aşağıdaki komutu çalıştırın.
<workers-num>değerini stres işlemi sayısı ile ve<malloc-size-per-workers>değerini işlem başına ayrılan bellek miktarıyla değiştirin.NotSanal çekirdekler Redis pod'una bağlandığından, yerel bellek tükenip taşma uzak NUMA düğümlerine yayılana kadar yerel NUMA belleği öncelikli olarak ona ayrılır. NUMA düğümü başına bellek kullanımını kontrol etmek ve parametreleri buna göre ayarlamak için
numactl -Hkomutunu çalıştırın.numactl --membind=<numa-id> stress -m <workers-num> --vm-bytes <malloc-size-per-workers>
-
-
Hızlandırma devre dışı ve etkin durumdayken stres testleri çalıştırın.
-
Hızlandırma devre dışıyken stres testi
redis-server üzerinde orta ve yüksek düzeyde yük oluşturmak için stres testi makinesinden istekler gönderin.
-
500 eşzamanlı istek (orta yük):
redis-benchmark -t GET -c 500 -d 4096 -n 2000000 -h <redis-server-IP> -p <redis-server-port> -
10.000 eşzamanlı istek (yüksek yük):
redis-benchmark -t GET -c 10000 -d 4096 -n 2000000 -h <redis-server-IP> -p <redis-server-port>
-
-
Yakındaki bellek erişimi hızlandırmayı etkinleştirin
Redis pod'u için hızlandırmayı etkinleştirmek üzere aşağıdaki komutu çalıştırın:
kubectl annotate pod redis koordinator.sh/memoryLocality='{"policy": "BestEffort"}' --overwriteTaşımanın tamamlandığını doğrulayın:
kubectl describe pod redisBeklenen çıktı (büyük hacimli uzak belleğin taşınması zaman alabilir):
Normal MemoryLocalitySuccess 0s koordlet-resmanager migrated memory from remote numa: 0 to local numa: 1, cur local memory ratio 98, rest remote memory pages 28586 -
Hızlandırma etkin durumdayken stres testi
Orta ve yüksek düzeyde yük oluşturmak için a adımındaki stres testlerini tekrarlayın.
-
ecs.ebmc8i.48xlarge sonuçları
Bellek dağılımı: Hızlandırmadan önce %43 yerel, hızlandırmadan sonra %98 yerel.

-
500 eşzamanlı istek
Senaryo
P99 ms
P99.99 ms
QPS
Hızlandırmadan önce
3
9,6
122.139,91
Hızlandırmadan sonra
3
8,2
129.367,11P99 gecikme süresi değişmedi. P99.99 gecikme süresi %14,58 azaldı. QPS %5.917 arttı.
-
10.000 eşzamanlı istek
Senaryo
P99 ms
P99.99 ms
QPS
Hızlandırmadan önce
115
152,6
119.895,56
Hızlandırmadan sonra
101
145,2
125.401,44P99 gecikme süresi %12,17 azaldı. P99.99 gecikme süresi %4,85 azaldı. QPS %4,59 arttı.
ecs.ebmg7a.64xlarge sonuçları
Bellek dağılımı: Hızlandırmadan önce %47 yerel, hızlandırmadan sonra %88 yerel.

-
500 eşzamanlı istek
Senaryo
P99 ms
P99.99 ms
QPS
Hızlandırmadan önce
2,4
4,4
135.180,99
Hızlandırmadan sonra
2,2
4,4
136.296,37P99 gecikme süresi %8,33 azaldı. P99.99 gecikme süresi değişmedi. QPS %0,83 arttı.
-
10.000 eşzamanlı istek
Senaryo
P99 ms
P99.99 ms
QPS
Hızlandırmadan önce
58,2
80,4
95.757,10
Hızlandırmadan sonra
56,6
76,8
97.015,50P99 gecikme süresi %2,7 azaldı. P99.99 gecikme süresi %4,4 azaldı. QPS %1,3 arttı.
Sonuç: Uygulama verilerinin uzak NUMA düğümlerine kaydığı yüksek bellek yükü altında, sanal çekirdeklerin bağlanması ve yakındaki bellek erişimi hızlandırmanın etkinleştirilmesi, hem orta hem de yüksek eşzamanlılık durumunda Redis için erişim gecikme süresini azaltır ve aktarım hızını artırır.