VLDB顶会论文Async-fork解读与Redis在得物的实践(4)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: VLDB顶会论文Async-fork解读与Redis在得物的实践

6.2 Async-fork 适配优化

针对找出来的代码位置,可以进行相应优化,针对此处的日志影响,我们可以屏蔽日志或者将日志移动到子进程进行打印,通过同样的分析手段,如果存在其他影响,均可进行对应优化。进行相应适配优化修改后,我们再次进行测试。

 测试环境

Redis版本:优化后Redis-Server

机器操作系统:Tair专属操作系统镜像

测试数据量:54.38G

127.0.0.1:6680> info memory
# Memory
used_memory:58385641144
used_memory_human:54.38G

现象

在压测过程中执行bgsave,fork耗时和TP100均正常。

使用 info stats 返回上次fork耗时:latest_fork_usec:414

TP100结果如下:

# 压测过程中执行 bgsave
[root@xxx Redis]# /usr/bin/Redis-benchmark -d 256 -t set -n 1000000  -a dRedis123456 -p 6680
====== SET ======
  1000000 requests completed in 7.50 seconds
  50 parallel clients
  256 bytes payload
  keep alive: 1
99.99% <= 1 milliseconds
99.99% <= 2 milliseconds
100.00% <= 2 milliseconds
133386.69 requests per second

跟踪验证

再次使用strace和perf工具跟踪验证

strace跟踪父进程只看到clone,并且耗时只有378微秒,

# strace -p 14697 -T -tt -o strace04.out
14:42:00.723224 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fa5340d0a50) = 15470 <0.000378>

Perf trace跟踪父进程也只看到clone调用

# perf trace -p 14697 -o trace04.out --max-stack 15 -T
618249694.830 ( 0.423 ms): Redis-server/14697  ... [continued]: clone()) = 15470 (Redis-server)
                                       __GI___fork (inlined)
                                       rdbSaveBackground (/usr/local/Redis/Redis-server)
                                       bgsaveCommand (/usr/local/Redis/Redis-server)
                                       call (/usr/local/Redis/Redis-server)
                                       processCommand (/usr/local/Redis/Redis-server)
                                       processInputBuffer (/usr/local/Redis/Redis-server)
                                       aeProcessEvents (/usr/local/Redis/Redis-server)
                                       aeMain (/usr/local/Redis/Redis-server)
                                       main (/usr/local/Redis/Redis-server)

由于我们的优化是将触发mmap的相关日志修改到子进程中,使用Perf trace跟踪fork产生的子进程,命令为:

strace -p 14697 -T -tt -f -ff -o strace05.out

通过Redis日志文件找到子进程pid为15931;打开对应生成的保存子进程strace信息的文件strace05.out.15931(父进程strace信息保存在文件 strace05.out.14697)

# 以下为子进程 strace 信息
14:47:40.878387 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa5340da000 <0.000008>
14:47:40.878415 write(6, "15931:C 21 Mar 14:47:40.878 * Ba"..., 69) = 69 <0.000015>
14:47:40.878447 close(6)                = 0 <0.000006>
14:47:40.878467 munmap(0x7fa5340da000, 4096) = 0 <0.000010>
14:47:40.878494 open("temp-15931.rdb", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6 <0.000020>
14:47:40.878563 fstat(6, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 <0.000006>
14:47:40.878584 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa5340da000 <0.000006>

在子进程中看到了mmap调用,子进程中调用不会影响父进程对业务访问的响应。


7. 性能测试

修改Redis代码,针对Async-fork适配优化后,我们针对fork与Async-fork进行了性能对比测试;测试包含不同数据量下fork()命令耗时与fork()操作对压测过程中TP100的影响。


7.1 fork()命令耗时

fork()命令耗时,即针对Redis执行 bgsave 命令后,通过Redis提供的 info stats 命令观察到的 latest_fork_usec 用时。

image.png

注:由于fork与Async-fork系统下,fork()操作产生的 latest_fork_usec 数据差距悬殊非常大,使用单纵轴会导致Async-fork的数据在图表中显示不明显,不方便查看,因此, 该图表使用了双纵轴;虽然Async-fork的图表看起来比较高,但是实际右纵轴范围小,所以数据小。

从图表可以看出,使用支持Async-fork的操作系统,fork()操作产生的耗时非常小,不管数据量多大,耗时都非常稳定,基本在200微秒左右;而原生fork产生的耗时会随着数据量增长而增长,而且是从几十毫秒增长到几百毫秒。


7.2 TP100抖动

在使用Redis-benchmark压测过程中,手动执行bgsave命令,触发操作系统fork()操作,观察不同数据量下,fork与Async-fork对Redis压测时TP100的影响。

image.png

从图上可以看出,使用支持Async-fork的操作系统,fork()操作对Redis压测产生的性能影响非常小,性能提升非常明显,不管数据量多大,耗时都非常稳定,基本在1-2毫秒左右;而原生fork产生的抖动影响时间会随着数据量增长而增长,TP100从几十毫秒增长到几百毫秒。


8. 总结

通过不同数据量下对比测试,我们可以看到,Async-fork相比原生fork,阻塞时间大大减少,性能提升非常明显。而且阻塞时间非常稳定,不会因为数据量的增长出现倍数级增长。

在单机测试场景下,8G数据量大小下,TP100和 latest_fork_usec 耗时均减少98% 以上。

基于论文中Async-fork的设计思想,Tair专属操作系统镜像已支持该特性,并且将该特性集成在原生fork 中,没有新增系统调用接口,理论上用户只需要使用支持Async-fork的操作系统,程序无需做任何修改,就可以享受到Async-fork特性带来的性能提升。对于Redis而言,我们也只需要对Redis稍加适配就可以获得该技术带来的红利。

在Redis应用场景中,在添加从节点、RDB文件备份、AOF持久化文件重写等场景下,应用支持Async-fork的操作系统,都将极大的减少对业务的影响。


参考资料:

[1] 《Async-fork: Mitigating Query Latency Spikes Incurred by the Fork-based Snapshot Mechanism from the OS Level》

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
3月前
|
存储 缓存 NoSQL
蚂蚁金服P7私藏的Redis原理与实践内部笔记
Redis 是完全开源免费的,是一个高性能的key-value类型的内存数据库。整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。
61 1
|
4月前
|
缓存 NoSQL Java
Spring Cache 缓存原理与 Redis 实践
Spring Cache 缓存原理与 Redis 实践
170 0
|
6月前
|
NoSQL 测试技术 Linux
VLDB顶会论文Async-fork解读与Redis在得物的实践(3)
VLDB顶会论文Async-fork解读与Redis在得物的实践
66 0
VLDB顶会论文Async-fork解读与Redis在得物的实践(3)
|
6月前
|
NoSQL 测试技术 Linux
VLDB顶会论文Async-fork解读与Redis在得物的实践(2)
VLDB顶会论文Async-fork解读与Redis在得物的实践
36 0
VLDB顶会论文Async-fork解读与Redis在得物的实践(2)
|
2月前
|
弹性计算 NoSQL 测试技术
倚天使用|Redis性能高30%,阿里云倚天ECS性能摸底和迁移实践
Redis在倚天ECS环境下与同规格的基于 x86 的 ECS 实例相比,Redis 部署在基于 Yitian 710 的 ECS 上可获得高达 30% 的吞吐量优势。成本方面基于倚天710的G8y实例售价比G7实例低23%,总性价比提高50%;按照相同算法,相对G8a,性价比为1.4倍左右。
137511 5
|
5月前
|
JSON NoSQL Java
SpringBoot2.0整合Redis实践详解
SpringBoot2.0整合Redis实践详解
62 2
|
5月前
|
NoSQL Linux Redis
Redis基础入门实践详解
Redis基础入门实践详解
50 1
|
6月前
|
存储 NoSQL 中间件
GitHub数据库榜单第一:Redis核心原理实践PDF,点赞已过百万+
Redis是互联网技术领域使用最为广泛的存储中间件,它是「Remote DictionaryService」的首字母缩写,也就是「远程字典服务」。Redis 以其超高的性能、完美的文档、简洁易懂的源码和丰富的客户端库支持在开源中间件领域广受好评。国内外很多大型互联网公司都在使用Redis, 比如Twitter、YouPom、暴雪娱乐、Github、StackOverflow、 腾讯、阿里、京东、华为、新浪微博等等,很多中小型公司也都有应用。也可以说,对Redis的了解和应用实践已成为当下中高级后端开发者绕不开的必备技能。
|
21天前
|
存储 NoSQL 算法
09- Redis分片集群中数据是怎么存储和读取的 ?
Redis分片集群使用哈希槽分区算法,包含16384个槽(0-16383)。数据存储时,通过CRC16算法对key计算并模16383,确定槽位,进而分配至对应节点。读取时,根据槽位找到相应节点直接操作。
54 12