大數據“復活”記
587
2025-04-02
目錄導航
訪問大key
刪除大key
大key對GaussDB(for Redis)擴容操作的影響
總結
在前一篇文章《墨天輪評測:GaussDB(for Redis)穩定性與擴容表現》?中,我們使用多線程壓測工具memtier_benchmark對華為GaussDB(for Redis)和原生Redis進行了對比壓測,發現原生Redis容易出現OOM故障,且擴容操作會很慢,給運維帶來很大壓力。反觀華為GaussDB(for Redis)不僅性能穩定,還具備在壓測過程中秒級擴容的能力,擴容操作對業務讀寫無影響。華為GaussDB(for Redis)支持全量數據落盤,GaussDB基礎組件服務提供底層數據三副本冗余保存,能夠保證數據零丟失。如果使用場景既要滿足KV查詢的高性能,又希望數據得到重視能夠不丟,則華為GaussDB(for Redis)是合適的選型。
我們大多在實際生產環境中都遇到過big key對Redis性能的嚴重影響。接下來我們通過幾個簡單的實驗,測試下對于大key這一“性能殺手”,GaussDB(for Redis)的表現怎樣,和原生Redis相比在性能上有哪些改進?
1、訪問大key
首先分別在GaussDB(for Redis)和原生redis中創建一個大的hash類型的key。
編輯一個簡單的lua腳本,向一個hash key中插入一千萬條數據。
# vim redis-bigkey.lua local result for var=1,10000000,1 do redis.call('hset',KEYS[1],var,var) redis.call('lpush',KEYS[2],var) redis.call('sadd',KEYS[3],var) end return result
向GaussDB(for Redis)【192.168.0.226:8635】中插入大key
# redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 --eval /root/redis-bigkey.lua 3 hset_test list_test set_test (nil) # redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 hlen hset_test (integer) 10000000 # redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 scard sadd_test (integer) 10000000 # redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 llen lpush_test (integer) 10000000
向原生Redis【192.168.0.135】中插入大key
# redis-cli -h 192.168.0.135 -a XXXXXXX -p 6379 --eval /root/redis-bigkey.lua 3 hset_test list_test set_test (nil) # redis-cli -h 192.168.0.135 -a XXXXXXX -p 6379 hlen hset_test (integer) 10000000 # redis-cli -h 192.168.0.135 -a XXXXXXX -p 6379 scard sadd_test (integer) 10000000 # redis-cli -h 192.168.0.135 -a XXXXXXX -p 6379 llen lpush_test (integer) 10000000
使用memtier_benchmark模擬業務壓力的同時 對大key進行訪問,觀察對業務qps的影響。
編輯一個簡單shell腳本,對大key進行頻繁的訪問
#!/bin/bash while true do redis-cli -h 192.168.0.135 -a XXXXXXX -p 6379 hget hset_test $RANDOM redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 hget hset_test $RANDOM redis-cli -h 192.168.0.135 -a XXXXXXX -p 6379 LREM lpush_test 0 $RANDOM redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 LREM lpush_test 0 $RANDOM redis-cli -h 192.168.0.135 -a XXXXXXX -p 6379 SISMEMBER sadd_test $RANDOM redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 SISMEMBER sadd_test $RANDOM done
使用memtier_benchmark進行壓測,讀寫混合場景。通過反饋的性能數據可以看到 GaussDB(for Redis) 和Redis每秒的操作數ops/sec 分別為14萬和13萬,差別不大。
#GaussDB(for Redis) memtier_benchmark -s 192.168.0.226 -a XXXXXXX -p 8635 -c 16 -t 12 -n 100000 --random-data --randomize --distinct-client-seed -d 1000 --key-maximum=65000000 --key-minimum=1 --key-prefix= --ratio=1:1 --out-file=./result_gauss_setget.log [RUN #1] Preparing benchmark client... [RUN #1] Launching threads now... [RUN #1 3%, 4 secs] 12 threads: 582045 ops, 144053 (avg: 145472) ops/sec, 21.16MB/sec (avg: 21.51MB/sec), 1.33 (avg: 1.32) msec latency #原生Redis memtier_benchmark -s 192.168.0.135 -a XXXXXXX -p 6379 -c 16 -t 12 -n 100000 --random-data --randomize --distinct-client-seed -d 1000 --key-maximum=65000000 --key-minimum=1 --key-prefix= --ratio=1:1 --out-file=./result_redis_setget.log [RUN #1] Preparing benchmark client... [RUN #1] Launching threads now... [RUN #1 7%, 11 secs] 12 threads: 1430798 ops, 132637 (avg: 130051) ops/sec, 70.51MB/sec (avg: 68.79MB/sec), 1.44 (avg: 1.47) msec latency
啟動shell腳本后再次觀察,發現GaussDB(for Redis) 的每秒操作數幾乎無變化,而原生Redis的每秒操作數波動巨大,甚至降低到了3k左右。說明大key操作對原生Redis性能有較大影響,對GaussDB(for Redis) 的影響可控。
# bash hget_bigkey.sh #GaussDB(for Redis) # memtier_benchmark -s 192.168.0.226 -a XXXXXXX -p 8635 -c 16 -t 12 -n 100000 --random-data --randomize --distinct-client-seed -d 1000 --key-maximum=65000000 --key-minimum=1 --key-prefix= --ratio=1:1 --out-file=./result_gauss_setget.log [RUN #1] Preparing benchmark client... [RUN #1] Launching threads now... [RUN #1 47%, 64 secs] 12 threads: 9099444 ops, 139186 (avg: 142163) ops/sec, 20.60MB/sec (avg: 20.96MB/sec), 1.38 (avg: 1.35) msec latency #原生Redis # memtier_benchmark -s 192.168.0.135 -a XXXXXXX -p 6379 -c 16 -t 12 -n 100000 --random-data --randomize --distinct-client-seed -d 1000 --key-maximum=65000000 --key-minimum=1 --key-prefix= --ratio=1:1 --out-file=./result_redis_setget.log [RUN #1] Preparing benchmark client... [RUN #1] Launching threads now... [RUN #1 29%, 75 secs] 12 threads: 5607700 ops, 3329 (avg: 74759) ops/sec, 1.80MB/sec (avg: 40.08MB/sec), 52.35 (avg: 2.55) msec latencyy
2、刪除大key
繼續使用memtier_benchmark對GaussDB(for Redis) 和原生Redis進行測試,只讀場景。在GaussDB(for Redis)中刪除大key很快就能完成,且對性能幾乎無影響。
#GaussDB(for Redis) # memtier_benchmark -s 192.168.0.226 -a XXXXXXX -p 8635 -c 16 -t 12 -n 100000 --random-data --randomize --distinct-client-seed -d 1000 --key-maximum=65000000 --key-minimum=1 --key-prefix= --ratio=0:1 --out-file=./result_gauss_setget.log Writing results to ./result_gauss_setget.log... [RUN #1] Preparing benchmark client... [RUN #1] Launching threads now... [RUN #1 4%, 5 secs] 12 threads: 719216 ops, 151326 (avg: 143795) ops/sec, 22.16MB/sec (avg: 21.13MB/sec), 1.27 (avg: 1.33) msec latency # time redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 del sadd_test (integer) 1 real 0m0.003s user 0m0.001s sys 0m0.002s # memtier_benchmark -s 192.168.0.226 -a XXXXXXX -p 8635 -c 16 -t 12 -n 100000 --random-data --randomize --distinct-client-seed -d 1000 --key-maximum=65000000 --key-minimum=1 --key-prefix= --ratio=0:1 --out-file=./result_gauss_setget.log Writing results to ./result_gauss_setget.log... [RUN #1] Preparing benchmark client... [RUN #1] Launching threads now... [RUN #1 42%, 57 secs] 12 threads: 8031731 ops, 144874 (avg: 140890) ops/sec, 21.46MB/sec (avg: 20.77MB/sec), 1.32 (avg: 1.36) msec latency
反觀原生Redis,刪除大key耗時3秒,且在刪除期間對性能影響較大。可以觀察到在刪除期間ops/sec 變成0,也就是說大key刪除期間操作是沒有辦法正常響應的。
#原生Redis # memtier_benchmark -s 192.168.0.135 -a XXXXXXX -p 6379 -c 16 -t 12 -n 100000 --random-data --randomize --distinct-client-seed -d 1000 --key-maximum=65000000 --key-minimum=1 --key-prefix= --ratio=0:1 --out-file=./result_redis_setget.log Writing results to ./result_redis_setget.log... [RUN #1] Preparing benchmark client... [RUN #1] Launching threads now... [RUN #1 6%, 7 secs] 12 threads: 1107132 ops, 157621 (avg: 158125) ops/sec, 16.07MB/sec (avg: 16.13MB/sec), 1.22 (avg: 1.21) msec latency # time redis-cli -h 192.168.0.135 -a XXXXXXX -p 6379 del sadd_test (integer) 1 real 0m3.001s user 0m0.000s sys 0m0.003s # memtier_benchmark -s 192.168.0.135 -a XXXXXXX -p 6379 -c 16 -t 12 -n 100000 --random-data --randomize --distinct-client-seed -d 1000 --key-maximum=65000000 --key-minimum=1 --key-prefix= --ratio=0:1 --out-file=./result_redis_setget.log Writing results to ./result_redis_setget.log... [RUN #1] Preparing benchmark client... [RUN #1] Launching threads now... [RUN #1 57%, 68 secs] 12 threads: 1015893 ops, 0 (avg: 126961) ops/sec, 0.00KB/sec (avg: 12.98MB/sec), -nan (avg: 1.13) msec latencyy
手動刪除大key對性能的影響差別明顯,如果設置大key的過期時間交由Redis刪除過期數據 是否會有性能影響呢?下面簡單測試下
手動設置大key的過期時間,并啟動memtier_benchmark讀寫混合測試,查看對性能的影響。通過測試發現大key的過期對于GaussDB(for Redis)的性能幾乎沒有影響。
#GaussDB(for Redis) [root@ecs-ef13-0001 ~]# redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 EXPIRE sadd_test 8 && redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 EXPIRE sadd_test1 12 (integer) 1 (integer) 1 [root@ecs-ef13-0001 ~]# memtier_benchmark -s 192.168.0.226 -a XXXXXXX -p 8635 -c 16 -t 12 -n 10000 --random-data --randomize --distinct-client-seed -d 1000 --key-maximum=65000 --key-minimum=1 --key-prefix= --ratio=1:1 --out-file=./result_gauss_setget.log Writing results to ./result_gauss_setget.log... [RUN #1] Preparing benchmark client... [RUN #1] Launching threads now... [RUN #1 100%, 17 secs] 0 threads: 1920000 ops, 106367 (avg: 109940) ops/sec, 105.02MB/sec (avg: 108.55MB/sec), 1.74 (avg: 1.74) msec latency
在對原生Redis測試時,我們發現大key過期操作幾乎阻塞了正常的讀寫,在memtier_benchmark測試時ops/sec 指標為0,只有當大key過期操作結束后才恢復正常。
#原生Redis [root@ecs-ef13-0001 ~]# redis-cli -h 192.168.0.135 -a XXXXXXX -p 6379 EXPIRE sadd_test 8 && redis-cli -h 192.168.0.135 -a XXXXXXX -p 6379 EXPIRE sadd_test1 12 (integer) 1 (integer) 1
[root@ecs-ef13-0001 ~]# memtier_benchmark -s 192.168.0.135 -a XXXXXXX -p 6379 -c 16 -t 12 -n 10000 --random-data --randomize --distinct-client-seed -d 1000 --key-maximum=65000 --key-minimum=1 --key-prefix= --ratio=1:1 --out-file=./result_redis_setget.log Writing results to ./result_redis_setget.log... [RUN #1] Preparing benchmark client... [RUN #1] Launching threads now... [RUN #1 100%, 42 secs] 0 threads: 1920000 ops, 134502 (avg: 45551) ops/sec, 132.80MB/sec (avg: 44.98MB/sec), 1.43 (avg: 4.21) msec latency
開源redis的過期雖然也支持異步,但需要用戶手動配置策略;刪除操作則需用UNLINK替換常規的DEL,具體對性能的影響可能會有所降低,本次不做深入驗證。華為GaussDB(for Redis)的刪除和過期對性能0影響。
3、大key對GaussDB(for Redis)擴容操作的影響
在上一篇文章中我們測試了GaussDB(for Redis)的在線擴容功能,經測試GaussDB(for Redis)可以在不影響業務讀寫的前提下實現秒級的擴容。這次我們增加一些“難度”,看看存在大key的情況下GaussDB(for Redis)擴容操作是否還能做到秒級和業務零感知。
預先在GaussDB(for Redis)中插入大key
[root@ecs-ef13-0001 ~]# redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 scard sadd_test4 (integer) 10000000 [root@ecs-ef13-0001 ~]# redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 scard sadd_test5 (integer) 10000000 [root@ecs-ef13-0001 ~]# redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 scard sadd_test6 (integer) 10000000 [root@ecs-ef13-0001 ~]# redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 scard sadd_test7 (integer) 10000000 [root@ecs-ef13-0001 ~]# redis-cli -h 192.168.0.226 -a XXXXXXX -p 8635 scard sadd_test8 (integer) 10000000
使用memtier_benchmark模擬讀寫請求,同時在控制臺上進行擴容操作。同之前的測試效果一樣,GaussDB(for Redis)同樣實現了對業務零感知的秒級擴容
[root@ecs-ef13-0001 ~]# memtier_benchmark -s 192.168.0.226 -a XXXXXXX -p 8635 -c 16 -t 12 -n 50000 --random-data --randomize --distinct-client-seed -d 1000 --key-maximum=65000 --key-minimum=1 --key-prefix= --ratio=0:1 --out-file=./result_gauss_setget.log Writing results to ./result_gauss_setget.log... [RUN #1] Preparing benchmark client... [RUN #1] Launching threads now... [RUN #1 9%, 20 secs] 12 threads: 902361 ops, 42634 (avg: 45112) ops/sec, 41.99MB/sec (avg: 44.44MB/sec), 4.53 (avg: 4.23) msec latencycy
4、總結
原生Redis對大key的訪問,刪除等操作會嚴重阻塞業務的正常訪問,這是由Redis自身單線程處理請求的架構決定的。使用原生Redis時需要嚴格限制大key的使用,一旦出現大key對系統的性能影響通常是“
致命
”的。
反觀GaussDB(for Redis)由于采用多線程架構,對大key的訪問、刪除,以及存在大key情況下的擴容操作,對性能的影響都是可控的。
1)大key訪問場景中,由于GaussDB(for Redis)采用的多線程的架構,不易阻塞其他業務操作。
2)大key刪除的場景中,由于GaussDB(for Redis)實現的邏輯不同,刪除操作能夠快速完成,對業務無影響。
3)擴容場景中,GaussDB(for Redis)不涉及key遷移,大key對擴容更是0影響。
綜上,雖然一般推薦業務設計避免大key,但在一些需要操作少量大key的業務場景,華為云GaussDB(for Redis)表現更佳。
此外,從業務開發角度看,當多業務共用一個實例時,使用GaussDB(for Redis)的話,即使其他業務引入大key,自己的業務也不至于受太大影響。
MySQL Redis 數據倉庫服務 GaussDB(DWS) 數據庫 緩存
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。