首页 新闻 会员 周边

高并发下redis性能问题

0
悬赏园豆:200 [已关闭问题] 关闭于 2017-05-18 14:38

我有一个类似秒杀活动,主要逻辑由redis支撑,考虑到可能的并发量,对redis进行了分片,在秒杀时候使用round robin方式从redis中进行秒杀逻辑(配合lua脚本),如果当前redis被秒杀完则会将当前redis从可用列表中排除后再次round robin到下一个redis上。整个同步请求流程有7次redis请求,redis请求命令(包括lua脚本)时间复杂度绝大部分为O(1),仅有少数O(logN)的操作。

现在情况是在并发1k时(tps 45k左右,并发500,tps37k),服务端计时日志(日志输出异步,服务端若干台,且cpu使用低于350%,24核)显示出来执行耗时会无规律偏高(频率大概在每万次上百,整理耗时会达到1s甚至更高)。

检查整个环境,redis主从(主关闭aof,rdb,仅同步,slave开启rdb,无哨兵,由其他方式进行主从切换,且调用地址通过域名方式指定,slave性能较master稍差,单机24核64G,redis整体内存开销不大,最大仅3G左右,有些甚至就记录几个数字,单机部署16实例),slowlog(由于其他原因无法知道slowlog的阈值)中无慢操作,各环节带宽开销均不大(最大250M),连接池考虑分片及服务端本身负载均衡因此单进程针对每个redis实例配置的数量均不大(100-128),testOnBorrow等均为false。redis机器上每个核cpu使用均不高(大部分为20%以下,有些由于做其他操作最大为70%)

服务端和前面说的一样,cpu使用率仅在350%以下,增加压力并不能提高cpu使用率,反而有衰减趋势(感觉某处资源受限后拖累整体),jvm日志中无full gc。

低负载情况下通过计时日志观察7步redis操作耗时总和基本控制在7ms内,甚至有些会下探到5ms(有个种子生成会进行预载,加载200个后停止,当一旦被使用后再次开始加载。且此处也使用分布式从redis递增获取种子)

检查很久都未发现瓶颈在哪,请问整个环节中有什么遗漏或者会导致性能变化的可能性

Daniel Cai的主页 Daniel Cai | 专家六级 | 园豆:10424
提问于:2017-05-08 11:47
< >
分享
所有回答(4)
0

好厉害~勉强能看懂

balahoho | 园豆:2050 (老鸟四级) | 2017-05-08 18:56
0

1、Redis是单线程的,直接影响了CPU的利用率

2、网卡也可能限制了

狼爷 | 园豆:1204 (小虾三级) | 2017-05-10 11:22

cpu这块我是直接看redis使用的核的使用率,这块数据和我问题中说的一样,而且slowlog中无慢查询。

网卡我前面也说了,最大250M,而服务器都是至少千兆网卡。

支持(0) 反对(0) Daniel Cai | 园豆:10424 (专家六级) | 2017-05-10 11:38
0

楼主 有2个问题我想请教下

1.redis 如果作为sql数据库的缓存的话 当数据出现修改时 同步策略怎么处理

2.对于 订单数据 最后提交 怎么保证并发效率? 数据 是提交到 redis 做持久化 有优势 还是 提交到sql 做持久化 有优势 这方面怎么考虑的?

 

能否帮我解答下 谢谢!

小眼睛老鼠 | 园豆:2731 (老鸟四级) | 2017-05-10 11:30

の。。。

1.两种方式,一种是惰性加载,附加超时,这种一般针对数据时效性及一致性较低的场景,但实现简单,先从缓存读,读不到对key加个分布式锁,然后去db捞,捞到回填缓存后释放锁。第二种只有老老实实的写缓存后写sql,一致性保证方案这个比较多,比如自己实现redis写的事务性或者补偿等

2.redis的持久化默认的两种,aof占用磁盘空间大,而且在收缩的时候会占用大量cpu,但适当的配置可以保证不丢数据(但性能会衰减)。rdb这种磁盘占用一般,这个主要看配置了,如果配置粒度过大可能会导致一段时间内丢数据(最小丢的话应该是1S内的数据)。

redis不存在并发性,仅仅是通过内部高效算法(比如跳表实现其他算法可能达不到的效率,比如zrange等)及无锁(这个对性能影响极大),所以redis的效率可以算是相当不错了,而且可以规避用sql中并发导致的需要各种锁的问题。

但针对你的问题我没办法给出绝对的答案,订单的引申含义就是需要数据的安全性,sql当然可以保证但性能上就要差点,redis如果使用默认方式来用性能上肯定会好些但数据安全性上就需要额外做很多文章了,此消彼长,如何权衡还是看你自己。

支持(0) 反对(0) Daniel Cai | 园豆:10424 (专家六级) | 2017-05-10 11:57

@Daniel Cai: 

第一个问题我想问的是 如果一个菜品 已经缓存到 redis了 然后客户下了单

这个时候 数据库 的菜品价格 被服务员调整了 怎么让缓存同步响应 这方面的策略有哪些

按楼主的意思 应该是 把菜品数据存入 redis 菜单 通过key去取单个菜品数据

我之前困扰的是 菜单会冗余 菜品信息 那么同步策略上就有实时实现的困难

关于第二个问题 我的考虑 和楼主 差不多 用sql 可以保证安全 但是性能上 会出现瓶颈 用redis 无法保证数据安全

 

非常感谢楼主解答

支持(0) 反对(0) 小眼睛老鼠 | 园豆:2731 (老鸟四级) | 2017-05-10 12:08

@小眼睛老鼠: 

你第一个问题我觉得要放弃又想要cache又想要强一致的这种想法。你为何在菜单上要冗余菜品的价格?就算冗余了那么我的理解就是最终价格就以菜单上的价格为准而不是以db中最后更新的价格为准。

如果你说实际价格已最终提交或者支付时为准的话那么你在最后从db中计算下价格信息不就可以了么?(考虑实际场景下单的压力远远大于支付的压力,所以在支付时去db问下这个不会有什么问题的)

第二个问题也不要太纠结,技术手段永远只是提高数据安全性的百分比后面9的数量,当一旦已经是0.999999999...的话那么就是可以确保。所以基于这点你做的所有尝试也就是为了这个9的数量,而不能绝对为1.如果你认同我的观点的话我可以提点建议

在操作时不要一次针对一个redis,只要换成同时操作n个redis(奇数台),那么最后你会拿到n个结果,n个结果中如果有超过1/2的是相同结果那么就是用这个结果,否则就认为整个操作是失败的。那么这样用的话整体可靠性就会随着你redis实例数量的增加而增加,要多少个9就取决于你对安全的看法了,但这种做法要想办法去规避脑裂问题。(使用此种做法的话最好有后续功能对不一致的结果的节点数据做修正,修正前要拿一个锁后从多数正确节点上拿取数据作为蓝本)

支持(0) 反对(0) Daniel Cai | 园豆:10424 (专家六级) | 2017-05-10 12:31

@小眼睛老鼠: 再ps下一点我的看法。以前忘了是看时间简史还是啥里面提到了熵的概念。如果你想压缩空气只需要拿个打气筒撸几下就好了,但如果你需要极端的压力整个时候就不是简单的多撸几下的问题,而是随着压力的增高(熵的减少)难度会成指数上升。

我觉得这个和要保证数据一致性安全性啥的一个道理,随着你的要求的提高额外做的事就会变的越来越复杂(站在现有技术水平的角度上看),到了某个点上可能就无法再逾越甚至复杂度已经无法再维护了,那么这个时候就不要再纠结那点瑕疵了,因为一个买彩票的几率才能碰到的数据问题会那么青睐你么?(引申含义不方便说)

支持(0) 反对(0) Daniel Cai | 园豆:10424 (专家六级) | 2017-05-10 12:41

@Daniel Cai: 谢谢楼主

支持(0) 反对(0) 小眼睛老鼠 | 园豆:2731 (老鸟四级) | 2017-05-10 15:22
0

楼主 我要 豆豆 大赏几个吧 ,

skateweb | 园豆:170 (初学一级) | 2017-05-23 14:54
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册