# ETCD IO 效能測試 ## 安裝 benchmark * 需先安裝 go 1.21 以上版本 ``` $ SUSEConnect -p sle-module-desktop-applications/15.5/x86_64 $ SUSEConnect -p sle-module-development-tools/15.5/x86_64 $ zypper install go-1.23-150000.3.38.1 $ go version go version go1.23.1 linux/amd64 ``` * 安裝 benchmark ``` $ git clone https://github.com/etcd-io/etcd.git; cd etcd $ go install -v ./tools/benchmark $ mv $(go list -f "{{.Target}}" ./tools/benchmark) /usr/local/bin/benchmark $ benchmark --help ``` ## rke2 測試 * put 測試(寫入),這個測試會發送 10000 個 put 操作 ``` $ benchmark --endpoints=127.0.0.1:2379 --cert /var/lib/rancher/rke2/server/tls/etcd/server-client.crt --key /var/lib/rancher/rke2/server/tls/etcd/server-client.key --cacert /var/lib/rancher/rke2/server/tls/etcd/server-ca.crt put --key-size=8 --val-size=256 --total=10000 ``` * range 測試(讀取) ``` $ benchmark --endpoints=127.0.0.1:2379 --cert /var/lib/rancher/rke2/server/tls/etcd/server-client.crt --key /var/lib/rancher/rke2/server/tls/etcd/server-client.key --cacert /var/lib/rancher/rke2/server/tls/etcd/server-ca.crt range 10000 --consistency=l --total=10000 ``` ## rke 測試 * put 測試(寫入),這個測試會發送 10000 個 put 操作 ``` $ benchmark --endpoints=127.0.0.1:2379 --cert /etc/kubernetes/ssl/kube-etcd-192-168-11-102.pem --key /etc/kubernetes/ssl/kube-etcd-192-168-11-102-key.pem --cacert /etc/kubernetes/ssl/kube-ca.pem put --key-size=8 --val-size=256 --total=10000 ``` * range 測試(讀取) ``` $ benchmark --endpoints=127.0.0.1:2379 --cert /etc/kubernetes/ssl/kube-etcd-192-168-11-102.pem --key /etc/kubernetes/ssl/kube-etcd-192-168-11-102-key.pem --cacert /etc/kubernetes/ssl/kube-ca.pem range 10000 --consistency=l --total=10000 ``` ## fio 測試 * 安裝 fio ``` $ curl -LO https://github.com/rancherlabs/support-tools/raw/master/instant-fio-master/instant-fio-master.sh $ bash instant-fio-master.sh # 在 sles 可以直接 install $ zypper in fio ``` * 測試 ``` # rke1 進到以下目錄 $ cd /var/lib/etcd/ # rke2 進到以下目錄 $ cd /var/lib/rancher/rke2/server/db/etcd $ mkdir test-data $ fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=100m --bs=2300 --name=mytest mytest: (g=0): rw=write, bs=(R) 2300B-2300B, (W) 2300B-2300B, (T) 2300B-2300B, ioengine=sync, iodepth=1 fio-3.23 Starting 1 process Jobs: 1 (f=1): [W(1)][100.0%][w=1265KiB/s][w=563 IOPS][eta 00m:00s] mytest: (groupid=0, jobs=1): err= 0: pid=27216: Tue Jan 7 17:00:52 2025 write: IOPS=470, BW=1057KiB/s (1082kB/s)(99.0MiB/96919msec); 0 zone resets clat (usec): min=8, max=320408, avg=832.45, stdev=3751.66 lat (usec): min=9, max=320408, avg=833.13, stdev=3751.67 clat percentiles (usec): | 1.00th=[ 12], 5.00th=[ 15], 10.00th=[ 18], 20.00th=[ 23], | 30.00th=[ 28], 40.00th=[ 41], 50.00th=[ 178], 60.00th=[ 229], | 70.00th=[ 281], 80.00th=[ 363], 90.00th=[ 734], 95.00th=[ 4883], | 99.00th=[ 14353], 99.50th=[ 19530], 99.90th=[ 43779], 99.95th=[ 56886], | 99.99th=[119014] bw ( KiB/s): min= 247, max= 1582, per=100.00%, avg=1057.02, stdev=227.47, samples=193 iops : min= 110, max= 704, avg=470.74, stdev=101.27, samples=193 lat (usec) : 10=0.32%, 20=15.28%, 50=25.76%, 100=1.35%, 250=21.52% lat (usec) : 500=22.97%, 750=2.95%, 1000=1.59% lat (msec) : 2=1.75%, 4=0.95%, 10=3.62%, 20=1.48%, 50=0.38% lat (msec) : 100=0.05%, 250=0.01%, 500=0.01% fsync/fdatasync/sync_file_range: sync (usec): min=544, max=136068, avg=1284.51, stdev=2380.34 sync percentiles (usec): | 1.00th=[ 652], 5.00th=[ 750], 10.00th=[ 816], 20.00th=[ 914], | 30.00th=[ 1004], 40.00th=[ 1074], 50.00th=[ 1156], 60.00th=[ 1221], | 70.00th=[ 1303], 80.00th=[ 1369], 90.00th=[ 1483], 95.00th=[ 1631], | 99.00th=[ 2540], 99.50th=[ 9765], 99.90th=[ 27132], 99.95th=[ 51643], | 99.99th=[111674] cpu : usr=0.83%, sys=15.67%, ctx=212612, majf=0, minf=15 IO depths : 1=200.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=0,45590,0,0 short=45590,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): WRITE: bw=1057KiB/s (1082kB/s), 1057KiB/s-1057KiB/s (1082kB/s-1082kB/s), io=99.0MiB (105MB), run=96919-96919msec ``` * fdatasync 的 99.00th 是 2540usec 等於 2.540 毫秒 (ms),寫入 WAL 檔案時 fdatasync 呼叫的第 99 個百分位必須小於 10 毫秒,就是好的 etcd IO 效能。 環境清除 ``` $ rm -r test-data/ ``` ## 優化方式 * 設定 etcd 容器的優先權,使其高於其他 process,但又不能太高導致壓垮伺服器。 ``` $ ionice -c2 -n0 -p `pgrep -x etcd` ``` ## rke1 * rke1 可以直接跑以下 container 來測試 ``` $ docker run --volume /var/lib/etcd/:/var/lib/etcd:Z quay.io/cloud-bulldozer/etcd-perf ...... }, "latency_depth" : 1, "latency_target" : 0, "latency_percentile" : 100.000000, "latency_window" : 0 } ] } -------------------------------------------------------------------------------------------------------------------------------------------------------- INFO: 99th percentile of fsync is 3981312 ns INFO: 99th percentile of the fsync is within the recommended threshold: - 10 ms, the disk can be used to host etcd ``` ## rke2 ``` $ echo 'apiVersion: v1 kind: Pod metadata: name: etcd-perf spec: restartPolicy: Never initContainers: - name: etcd-perf image: quay.io/cloud-bulldozer/etcd-perf volumeMounts: - name: etcd-data mountPath: /var/lib/etcd containers: - name: wait image: busybox command: ["sh", "-c", "sleep infinity"] lifecycle: postStart: exec: command: - /bin/sh - -c - | rm -rf /var/lib/etcd/etcd_perf.0.0 volumeMounts: - name: etcd-data mountPath: /var/lib/etcd volumes: - name: etcd-data hostPath: path: /var/lib/rancher/rke2/server/db/etcd type: Directory tolerations: - key: "node-role.kubernetes.io/control-plane" operator: "Exists" effect: "NoSchedule" nodeSelector: node-role.kubernetes.io/etcd: "true"' | kubectl apply -f - ``` * 檢查 log,以 10 ms 為基準,如果超過這個數值就會被判定為 etcd IO 效能太差。 ``` $ kubectl get pod NAME READY STATUS RESTARTS AGE etcd-perf 1/1 Running 0 108s $ kubectl logs etcd-perf -c etcd-perf ...... INFO: 99th percentile of fsync is 7176192 ns INFO: 99th percentile of the fsync is within the recommended threshold: - 10 ms, the disk can be used to host etcd $ kubectl delete pod etcd-perf ``` ## 參考 https://doczhcn.gitbook.io/etcd/index/index-1/performance https://www.suse.com/support/kb/doc/?id=000020100 https://access.redhat.com/solutions/4885641