- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
本文分享自华为云社区《墨天轮评测:GaussDB(for Redis)大Key操作的影响》,作者: 高斯 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 相比在性能上有哪些改进?
首先分别在 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.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
使用 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
继续使用 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 影响。
在上一篇文章中我们测试了 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
原生 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,自己的业务也不至于受太大影响。
继《GaussDB T分布式集群这样安装部署不踩坑》,我们开始GaussDB T每日维护必做的事情。新的一天从开启主机开始,把虚拟机打开后发现上次安装的数据库没有自启动,所有节点启动的相关进程仅
1、db2->gaussdb函数转换 问题描述:使用GaussDB替代DB2的方案,使用起来还是有些差别,做一下函数的映射转换。 DB2写法
本文分享自华为云社区《华为云GaussDB(for Influx)揭秘第八期:GaussDB(for Influx)与开源企业版性能对比》,作者:高斯Influx官方博客 。 “你们的数据库性能怎么样
本文分享自华为云社区《GaussDB(DWS)性能调优:DM区优化案例——维度表关联条件存在会计期》,作者: O泡果奶~。 当前DM(P1、P3、CBGDM)存在维度表与主表关联时使用会计期作为关联
**摘要:**本文将通过采用Redis Labs推出的多线程压测工具memtier_benchmark对比测试下GaussDB(for Redis) 和原生Redis的特性差异 本文分享自华为云社区《
对于金融类客户业务来说,经常会出现类似基于某些条件排他的查找,例如:基于客户ID、客户ID和业务ID的组合,查找不在某个特征范围内的用户集合等等。此类查询特定记录的使用场景,可以使用NOT IN的语法
对于金融类客户业务来说,经常会出现类似基于某些条件排他的查找,例如:基于客户ID、客户ID和业务ID的组合,查找不在某个特征范围内的用户集合等等。此类查询特定记录的使用场景,可以使用NOT IN的语法
近期,华为云GaussDB(for Redis)缓存数据库再次推出全新版本,携新特性重磅来袭!GaussDB(for Redis)是华为云推出的企业级分布式KV数据库,它完全兼容Redis协议,提供丰
作者,祝青平,华为云数据库内核高级工程师。 擅长数据库优化器内核研发,9年数据库内核研发经验,参与多个TP以及AP数据库的研发工作。 近日,华为云数据库社区下面有这样一条用户提问留言:
**摘要:**GaussDB(for Influx)通过提供hint功能,在单时间线的查询场景下,性能有大幅度的提升,能有效满足客户某些特定场景的查询需求。 本文分享自华为云社区《华为云GaussDB
**摘要:**复杂查询so easy!GaussDB(for Cassandra)新特性来袭。 本文分享自华为云社区《来了!GaussDB(for Cassandra)新特性亮相》,作者:GaussD
摘要: 智能把控大数据量查询,防患系统奔溃于未然。 本文分享自华为云社区《 拒绝“爆雷”!GaussDB(for MySQL)新上线了这个功能 》,作者:GaussDB 数据库。
**摘要:**华为云数据库高级内核技术专家详解GaussDB(for MySQL)Partial Result Cache特性,如何通过缓存中间结果对算子进行加速? 本文分享自华为云社区《GaussD
我是一名优秀的程序员,十分优秀!