redis集群系统的优化研究与实现xb.suse.edu.cn/xbzk/files/2020/6/20201222092441_7297.pdf ·...
TRANSCRIPT
-
第33卷第6期2020年12月
四川轻化工大学学报(自然科学版)
JournalofSichuanUniversityofScience&Engineering(NaturalScienceEdition)Vol33 No6Dec2020
收稿日期:20200610基金项目:国家自然科学基金项目(61902268);四川省科技计划项目(2018JY0197;20ZDYF0919);四川省教育厅项目(18ZA0357);德阳市
开放式校市合作技术研发项目(2018CKJSD017);人工智能四川省重点实验室项目(2017RZJ02);四川理工学院人才引进项目(2017RCL12)
作者简介:伍华锋(1996),男,四川德昌人,硕士生,主要从事分布式存储方面的研究,(Email)974191367@qq.com通信作者:王小刚(1984),男,陕西宝鸡人,讲师,博士,主要从事智能控制、物联网方面的研究,(Email)wxg_zf@163.com
文章编号:20967543(2020)06003907 DOI:10.11863/j.suse.2020.06.07
Redis集群系统的优化研究与实现
伍华锋,王小刚,候 劲,唐小林
(四川轻化工大学自动化与信息学院,四川 自贡 643000)
摘 要:现代互联网应用数据量大,并发高,对响应速率等要求极高。Redis作为高性能的分布式非
关系型数据库,在互联网应用中表现极佳。现今 Redis集群方案 RedisCluster有很多优越性,越来越多
的项目都期望从Redis迁移到Rediscluster上,但如果直接迁移,工作量和复杂性极高。因此在研究对比
当今流行的Redis集群系统架构设计和系统优化方案后,通过自研代理中间件Vc_redisproxy在代理中间
件中利用主从Reactor线程模型对原生Redis内部单一的NIO多路复用模型进行优化,使用MainReactor
处理连接请求,然后将连接交由SubReactor,由SubReactor来处理读写请求。然后使用线程池,通过增加
IO线程数来充分发挥多核CPU的优势,同时在代理中维护一张数据路由映射表,保证 IO效率最大化。
基于Rediscluster使用Java语言优化并实现了一种Redis集群系统。最后使用 RedisbenchMark工具对
系统进行压力测试。结果表明,单个Vc_redisproxy性能相对于Codis代理性能提升了17%,同时采用优
化后的系统框架后,部署两个Vc_redisproxy代理性能相比部署两个Codis代理性能提升了15%。
关键词:Redis集群;Reactor模式;路由映射;自研代理中间件
中图分类号:TP3111 文献标志码:A
引 言
现如今,大数据量的处理已经成为互联网应用的一
个常态。由于传统的关系型数据库放在磁盘上运行,会
导致相应的性能瓶颈,在解决大数据量的服务调用和并
发处理表现不佳[1]。Redis作为运行在内存上的一种高
性能非关系型数据库,读写速度比关系型数据库快得
多,同时其拥有丰富的数据结构,可以应对不同的互联
网应用场景[2]。而由于单机 Redis受自身内存、IO处理
等影响[3],并不能满足实际业务场景的需求。在实际生
产环境中,更多的是使用分布式的Redis集群。
Rediscluster相对于Redis而言,它能够实现自动故
障转移、迁移中数据访问、构建大容量集群等,有很多优
越性[4]。越来越多的项目都期望从 Redis迁移到 Redis
cluster上,从而提升项目吞吐量和稳定性[5]。但如果直
接进行迁移,客户端代码将会进行大面积的改造,工作
-
量和复杂性都极高[6]。如果可以通过一个代理中间件
来兼容Redis和Rediscluster,对于客户端代码就不用做
任何修改。
近年来越来越多的公司和相关研究学者关注 Redis
集群架构的设计和优化。
在系统架构设计方面,2016年,阿里云等公司使用
自研Proxy的方式搭建Redis集群,并且提供独立的组件
HA负责集群的主备切称。百度等公司基于C语言开发
对twemproxy进行改造,将Redis内核中的db划分成16384
个,请求下发到具体的 db上。京东等公司基于 Golang
语言开发自研 Proxy,同时增加 sentinal哨兵监控 Proxy
和Redis实例。
在系统优化方面,2017年,李轲[7]通过将 Redis服
务器实例和 CPU核绑定在一起,减少进程切换优化集
群。2018年,韦立[8]等人利用 Redis主从复制模式和备
份迁移策略,优化数据迁移策略。李罛[9]等人提出在
Rediscluster的基础上,所有节点通过一个集群总线连
接,在服务端通过总线去访问节点,从服务端数据访问
出发优化集群。2019年,韩雅丽[10]将OP_ACCEPT、OP_
READ、OP_WRITE事件分别注册到3个线程下对应的
选择器上,不同的事件对应不同的选择器,通过优化
Reactor模式优化集群。
本文对比现如今流行的 Redis集群方案,使用 Java
语言进行开发。在基于Proxy代理的方案上通过自研代
理中间件,在中间件中对传统的 Reactor模型进行优化,
充分发挥CPU多核优势,同时在代理中增加路由缓存表
以提升IO效率。
1 Redis集群方案对比
11 客户端分片
由客户端实现数据分片,并且将路由规则保存在客
户端[1112]。当客户端发送请求的时候,首先在客户端进
行路由计算,将请求转发到相应的 Redis实例中进行处
理,然后再将结果返回到客户端中。此方案中,客户端
的数据路由和业务处理逻辑强耦合在了一起,使得客户
端非常臃肿,不便于开发和后期维护[1315]。
12 Proxy方案
Proxy方案就是在 Redis的客户端和服务端之间添
加一个代理层,由代理完成数据分片和业务处理[16]。现
如今常见的代理中间件有Twemproxy和Codis,这种添加
代理层的优势很明显,简化了客户端,程序解耦出来,利
于后期的开发和升级。但是,这种方案由于在业务请求
过程中,增加了一层网络交互,导致性能有所下降,需通
过添加多个Proxy来提高性能。
13 服务端分片
服务端方案Rediscluster是 Redis官方提供的集群
方案,将集群看作是一个整体,统一进行数据分片,集群
总共被分为16384个哈希槽,所有的数据都会存放在哈
希槽上,这些哈希槽分布在集群的Redis节点上,节点之
间通过 Gossip协议进行通信[17]。RedisCluster支持动
态加入新节点,动态迁移 Slot,同时可以扩建大容量集
群,性能好。但是数据存储和分片逻辑耦合在了一起,
复杂性高,对运维和开发都引入了不可预估的风险和挑
战[1819]。
2 系统的部署架构
整个系统的总体框架如图1所示,结合 Proxy方案
和Rediscluster的优点进行改进。底层还是使用 Redis
cluster,保留其自动故障转移、迁移中数据访问等优点。
使用Proxy节点进行数据分片和请求路由,将程序解耦,
便于升级维护,同时使用主从 Reactor模型对现有的
Proxy方案进行优化。为了解决单个 Proxy路由转发带
来的性能损耗,部署多个 Proxy节点,将 Proxy节点服务
注册到 Zookeeper注册中心上,客户端通过拉取监听
Proxy列表,然后通过 LVS+Keepalived工具将请求进行
负载均衡,将命令分摊到多个Proxy节点处理,整个系统
的使用就可以像使用单机的 Redis一样方便。在本文
中,将优化的Redis代理称为Vc_redisproxy。
04 四川轻化工大学学报(自然科学版) 2020年12月
-
图1 系统总框架
3 Vc_redisproxy的具体实现
31 主从Reactor线程模型的引入
原生的Redis采用的是NIO多路复用技术的单进程
单线程模型,设计的初衷是为了减少多线程上下文切换
带来的性能损耗,但是这种模式只能使用一个 CPU核,
没有发挥多核的优势,随着多核CPU和网卡等技术的发
展,充分利用多核 CPU才是需要关注的重点[20]。针对
这个问题,本文基于主从 Reactor多线程模型进行改进,
如图2所示。Reactor主线程MainReactor对象当收到连
接请求后,产生 OP_ACCEPT事件交给 Acceptor单独处
理,创建连接,并将连接分配给 SubReactor。SubReactor
将连接加入到连接队列进行监听,当有读写请求过来的
时候,分别产生 OP_READ和 OP_WRITE事件,交由
SubReactor的选择器处理,然后将读写请求交由线程池,
由线程池中的IO线程进行读写。这种设计的最大优点
是使用父子线程将功能职责明确化了,父线程只需要接
受新的连接,而子线程则处理后序的读写请求,同时使
用了线程池的思想,充分的利用了多核 CPU,将性能最
大化。
32 路由缓存表的加入
本文系统底层选用的是 Rediscluster来搭建集群。
Rediscluster节点之间通过 Gossip协议进行交换信
息[21],每个节点都保存有集群中其他节点的信息,能很
好地进行动态缩容和扩容,具有自动故障转移等功能。
但由于Rediscluster自身通信的方式是由客户端发起请
求到集群中的任意节点,然后由节点进行 hash路由计
图2 Vc_redisproxy的架构图
算,找出请求的键对应的Slot,然后找到该Slot存放的节
点,如果发现节点就是自身,就进行相关的操作,如果发
现对应的节点并不是自身,就会发送一个 MOVED重定
向命令,同时包含正确的节点信息给客户端,客户端接
收到重定向命令之后,再次发送请求到正确的节点,完
成操作[22],如图3所示。这种方式下,在很大概率上,客
户端发送的请求都会请求两次,从而导致性能消耗。基
于此,本文在 Vc_redisproxy中维护一张数据路由表(表
1),当接收到请求时,Vc_redisproxy通过公式(1)进行计
算得到相应的 Slot,然后根据表1找到对应的 Redis节
点。通过这种方式,减少了 IO的请求次数,充分利用了
IO的效率。同时,当集群发生动态变更的时候,路由表
也能进行及时的更新。
图3 MOVED命令重定向过程
Slot=CRC16(key)&(16384-1) (1)
14第33卷第6期 伍华锋,等:Redis集群系统的优化研究与实现
-
表1 数据路由表
Slot 0 1 … 16832 16383
Node NodeA NodeC … NodeB NodeA
4 实验结果及分析
本次实验部署的实验室环境如下:
(1)硬件配置
CPU:Inter(R) Core(TM) i58300H CPU @
230GHz230(4核处理器);内存:16G;磁盘:256G;网
卡:千兆网卡。
(2)软件配置
操作系统:CentOSLinuxrelease711503(Linuxver
sion3100-229141el7x86_64);Redis:509;
Ruby:258;JDK:180_181。
基于上述环境,在3台虚拟机上搭建了6个 Redis
cluster节点,其中3个主节点、3个从节点。主从节点和
数据槽的分配情况见表 2,19216831107∶7001是
19216831109∶7006的主节点,19216831108∶7003
是19216831107∶7002的主节点,19216831109∶
7005是19216831108∶7004的主节点。
表2 主从节点和数据槽的分配情况主节点(Master) 从节点(Slave) 管理槽(Slot)
19216831107∶7001 19216831109∶7006 0-5460
19216831108∶7003 19216831107∶7002 5461-10922
19216831109∶7005 19216831108∶7004 10923-16383
每个Redis节点的配置信息都保存在自己节点对应
的redis.conf文件中。节点配置文件中的部分参数说明
见表3。
表3 redis.conf中部分参数说明参数设置 参数解释
Clusterenabledyes 开启集群
clusternodetimeout5000 集群的超时时间/ms
Appendonlyyes 打开AOF持久化
clusterconfigfilenodes_700x.conf 保存节点的配置,自动创建的
Maxmemory512M 节点的最大使用内存
maxmemorypolicyvolatilelru 当数据超出最大内存之后使用的拒绝策略
maxclients1000000 最大客户端连接数
41 路由测试
(1)原生Rediscluster集群的set操作
如图4所示,首先使用 rediscli命令连接集群中的
19216831116∶7001端口上的Redis实例,然后使用命
令“setbbwu”插入一个值,由图4可以看到,插入没有
成功,而是将“errorMOVED19216831117∶7003”信息
反馈给了客户端,由客户端重新连接19216831117∶
7003上的实例,然后重新进行 set插入操作。通过图4
可以直观地看出,一个set命令进行了两次操作。
图4 原生Redis集群的set过程
(2)Vc_redisproxy的set操作
如图 5所示,首先使用客户端命令连接运行在
17221737∶8089上的 Vc_redisproxy实例。因为在代
理中还加了一个权限认证操作,所以通过“authpwdol”
命令进行权限认证登录后,同样使用set命令进行插入,
由图5可以看出操作成功,并且返回了成功的提示信息
“setsuccessfulto19216831117∶7003”,说明set成功,
并将key为bb,value为wu的值,存放到了19216831117∶
7003这个节点。
图5 Vc_redisproxy的set操作
在分别对代理中加了路由缓存表和没有加路由缓
存表的情况分别进行压测,多次压测取平均值(客户端
50个,请求指数50万个),结果对比如图6所示。
42 Rediscluster集群压测
使用Redis自带的RedisbenchMark工具模拟50个客
户端,指定请求数为50万个。以测试单个Redis服务QPS
性能为例,压测命令为“./redisbenchmarkh19216831
24 四川轻化工大学学报(自然科学版) 2020年12月
-
图6 路由缓存压测
116p7001c50n500000tget,set”,压测结果如图7和图8
所示。
图7 单个Redis的set命令的压测结果
图8 单个Redis的get命令的压测结果
然后分别对直连 Rediscluster、单个 Vc_redisproxy
服务、两台Vc_redisproxy服务、单个 Codis代理服务(其
中Codis的版本为315)以及两台Codis服务进行常用
set命令和 get命令压测,压测多次取平均值,最终的结
果对比如图9和图10所示。
43 实验结果分析
(1)由图4和图5可以直观地看出,在代理中维护
路由缓存表,确实避免了通过Gossip协议的二次重定向
操作。当收到请求时,可以直接查询路由表,找到相应
的Redis节点,然后进行相应的操作。由图6可以看出,
图9 get命令QPS对比
图10 set命令QPS对比
相对于没有加路由缓存表的 Rediscluster集群,Vc_
redisproxy明显提升了处理性能。
(2)由图9和图10中set命令与get命令的QPS性
能对比可以直观地看出,相较于直连 Rediscluster,本文
自研的代理中间件Vc_redisproxy和现在比较成熟的Co
dis代理中间件性能都有所下降,但是 Vc_redisproxy相
较于 Codis性能又提升了17%左右。这是因为 Vc_re
disproxy中使用主从Reactor模型发挥了多核CPU性能,
通过维护路由缓存表避免了Gossip的重定向操作,保证
了IO效率的最大化。
在本文的系统部署架构中部署两个Codis服务或两
个Vc_redisproxy后,系统性能相对于直连 Redis又明显
34第33卷第6期 伍华锋,等:Redis集群系统的优化研究与实现
-
提升。同时,部署两个Vc_redisproxy的性能又比部署了
两个Codis服务的性能提升了15%左右。这是因为Zoo
keeper注册中心将两个服务进行统一管理后,LVS+
Keepalived工具将请求进行了负载均衡,将命令分摊到
了代理节点处理,通过横向添加代理节点的方式提高了
系统的性能。
(3)通过上述的实验结果对比分析可以看出,基于
本系统架构,自研的代理中间件Vc_redisproxy具有较为
优越的性能。
5 结束语
基于Proxy代理方案,通过引入Reactor主从模型对
连接请求和读写请求的分开处理,增加路由缓存表提高
IO效率,同时增加 IO线程池充分发挥 CPU核的作用,
实现了代理中间件Vc_redisproxy。相比现在流行的 Co
dis代理,Vc_redisproxy性能有明显提升。当然,随着网
卡等硬件技术的发展,充分发挥网卡性能是后续工作中
需要考虑的事情,在今后的研究中,可以尝试利用 By
pass内核用户态协议栈、多网络 IO线程等相关技术进
行优化集群。
参 考 文 献:
!"#
邱书洋%Y@=DB
缓存技术研究及应用!Q#%
郑州-
郑州大
学$'("U%
!'#
仝野%
基于3GV`[
数据库的系统设计与开发!Q#%
南
京-
南京邮电大学$'("*%
!0#
王续法%
基于Y@=DB
的一致性分析与改进!Q#%
成都-
电子科技大学$'("S%
!)#
黄裕%
基于分布式Y@=DB
集群的189
共享管理研
究!%
计算机与数字工程$'("*$)U+"(,-'(S*
'(*'$'"0(%
!/#
张博军%Y@=DB
缓存集群研究及其在0P
模式下的应
用!Q#%
武汉-
武汉理工大学$'("U%
!U#
高昕$
黄真%Y@=DB
集群在有轨电车车载系统中的应
用!%
现代城市轨道交通$'("*+',-"*
'($')%
!S#
李轲%
原生Y@=DB
集群的优化与实现!Q#%
武汉-
华中
科技大学$'("S%
!*#
韦立$
陈珊珊%
基于Y@=DB
单位最大效益自适应迁移
策略研究!%
计算机技术与发展$'("*$'*+"(,-/0
/*$
U0%
!.#
李罛$
刘利娜$
刘学敏$
等%
一种高效的Y@=DB 5>IB?@A
的
分布式缓存系统!%
计算机系统应用$'("*$'S+"(,-."
.*%
!"(#
韩雅丽%
分布式Y@=DB
高可用集群的设计与实现!Q#%
南
京-
南京大学$'(".%
!""#
周旭东%
基于Y@=DB
分布式存储的负载平衡及性能
优化研究!Q#%
南京-
南京邮电大学$'(".%
!"'#
周晓场%
基于Y@=DB
的分布式X@E
_:>I@
系统的优
化研究!Q#%
广州-
华南理工大学$'("*%
!"0#
李敏磊%
云环境下数据分布式缓存技术与应用!Q#%
南京-
南京邮电大学$'(".%
!")#
王绍东%
基于Y@=DB 5>IB?@A
的分布式内存数据库研
究与应用!Q#%
广州-
华南理工大学$'("U%
!"/#
王景佩%
基于Y@=DB
的结构化数据缓存系统的设计
与实现!Q#%
武汉-
华中科技大学$'("U%
!"U#
闫明%
高可用可扩展集群化Y@=DB
设计与实现!Q#%
西安-
西安电子科技大学$'(")%
!"S#
李邁%Y@=DB
集群可靠性的研究与优化!Q#%
合肥-
中
国科学技术大学$'("S%
!"*# NWXWY36 &% 3GV`[ =:?:C:B@B- : B?@K ?G =:?:C:B@
BF:>:CD>D?E D< 1@C @
-
方案的设计与实现!%
电子测试$'("U+U,-"U
"S%
!''#
王长城$
戚国庆$
李银伢$
等%
量化状态信息下多智能
体4GBBDK
算法及分布式优化!%
电子与信息学报$
'(")$0U+",-"'*
"0)%
ResearchandImplementationofOptimizationofRedisClusterSystem
WUHuafeng,WANGXiaogang,HOUJin,TANGXiaolin
(SchoolofAutomationandInformationEngineering,SichuanUniversityofScience&Engineering,Zigong643000,China)
Abstract:Nowadays,inInternetapplications,thereisalargeamountofdata,highconcurrency,andextremelyhigh
requirementsonresponserate.Asahighperformancedistributednonrelationaldatabase,Redisperformsverywellin
Internetapplications.TheRedisclustersolutionnowhasmanyadvantages.Moreandmoreprojectsareexpectedtomigrate
fromRedistoRediscluster,butiftheyaredirectlymigrated,theworkloadandcomplexityareextremelyhigh.Therefore,
afterresearchingandcomparingtoday'spopularRedisclustersystemarchitecturedesignandsystemoptimizationscheme,the
selfdevelopedproxymiddlewareVc_redisproxyusesthemasterslaveReactorthreadmodelintheproxymiddlewaretothe
singleNIOmultiplexingmodelinthenativeRedisTooptimize,useMainReactortoprocesstheconnectionrequest,andthen
handovertheconnectiontoSubReactor,whichwillprocessthereadandwriterequests.Thenusethethreadpooltogivefull
playtotheadvantagesofmulticoreCPUsbyincreasingthenumberofIOthreads,whilemaintainingaroutingmaptablein
theagenttoensuremaximumIOefficiency.ARedisclustersystemisoptimizedandimplementedbasedonRediscluster
usingJavalanguage.Finally,theRedisbenchMarktoolisusedtostresstestthesystem.Theresultsshowthatthe
performanceofasingleVc_redisproxyisimprovedby17% relativetotheperformanceoftheCodisproxy.Atthesametime,
afterusingtheoptimizedsystemframework,theperformanceofdeployingtwoVc_redisproxyproxiescomparedtothe
performanceofdeployingtwoCodisproxiesincreaseby15%.
Keywords:Rediscluster;Reactormode;routemapping;selfdevelopedagentmiddleware
54第33卷第6期 伍华锋,等:Redis集群系统的优化研究与实现