【第三讲,Redis的运维实战】
讲师:仲肥,阿里云NoSQL内核工程师;Redis Core Team member;
课程内容:Redis社区简介及运营方式介绍;云Redis的账号、监控、巡检、安全等性能介绍;审计,热点,大key等一般性解法;高级容灾。
答疑汇总:特感谢班委@邱谦 同学
Q1. 开源Redis在高并发连接下面存在的问题怎么修复?
比较早的时候,是贡献给社区的feature,发现问题会反馈给社区。Redis是怎么维护客户端的呢?它是存在一个list上,每次一个连接新建之后都会把这个连接的Client丢到一个list里面,在释放的时候,需要遍历这个list,这个时间复杂度是O(n),效率比较低。我们做了一个小优化,每次连接建立之后,不仅放入list里面,同时还记录下在list里的位置,可以实现在释放的时候只有O(1)的时间复杂度。本身Redis是单线程的,在高并发下虽然有epoll来做多路复用,但是本身的cpu只能用到一个核心,在多IO的时候(企业版),提升了网络的能力,连接量比较大的时候,会有更好的性能。
Q2. Redis建议做分布式锁吗?有什么有点或缺点?
主要看业务场景。Redis本身是不提供分布式锁的,但是可以用它去做一个分布式锁的方案,这个在控制台上的文档会有详细的介绍。优点是可以相对简单地搭建起来一个分布式锁系统,但在一些特别边缘地case上,可能会有一些死锁或者其他问题。
Q3. Redis集群如何提高性能?
最简单地方式就是扩节点,Redis虽然是单线程地,但是可以用多进程的方式,一个节点只能用一个cpu,两个节点可以用两个cpu,节点越多,性能吞吐就会越强。要注意的是社区的方案是要用SmartClient,需要做一些路由。如果后面的路由信息发生变化的话,客户端需要处理这些语义。云上有proxy这一层,也就是命令过来以后proxy本身会去做这些路由,把命令分发到不同的节点,使用起来和普通的主从版就没有什么区别。
Q4.Redis为何单线程效率这么高?为什么使用跳表不使用B+树?
Redis本身的跳表是在有序集合里用的数据结构。Redis的存储是用的哈希表,哈希表时间复杂度是O(1),但是会额外占用一些空间,是一种典型的用空间换时间的优化。虽然Redis是单线程的,但执行命令的路径是很短的。
Q5. 有没有办法看到集群版上某个节点是什么数据?
云上可以直接点到某个节点上面,如果有proxy,也提供自研的指定用某个DB节点迭代数据。
Q6. 单机Redis增加服务器CPU是否可以优化性能?
可以看一下Redis日常跑的时候,CPU到底跑到多少。工作线程是只有一个的,但还有一些bio线程,比如关文件,fsync等操作通常来说都不会占用也别多的CPU。最好还是观察一下。正常来说,社区版的Redis没有开6.0的多IO的话,2到3核的CPU已经足够了,再往上升也就没有什么太大的效果。
Q7. 秒杀场景是如何使用Redis的?
再后续的课程中(第六节)会详细的介绍这种使用场景。
Q8. 内存回收机制
Redis除了正常读写之外,还支持设置过期时间。到了过期时间之后,逻辑上是不能够再访问这个key了,但是它并不是马上做物理删除操作的,因为做物理删除需要做整个遍历,对于单线程的Redis来说任务就比较重。它会周期性地有一些任务,随机地挑选一些key,看它有没有过期,如果过期,那就做真正的物理删除。在访问这个key的时候,会提前看一下,看这个key有没有过期。如果过期,会主动删掉这个key。Redis还支持逐出操作。如果内存使用超过MaxMemory,就会挑一些key做逐出或者删除。这就要根据自己设置的MaxMemory策略来看了。从4.0之后,还支持对操作系统碎片进行整理回收,它也是后台的一种周期性任务,可以去遍历redis的key-value,看看能不能有优化的空间,但起到的作用有限。
Q9. 阿里的Redis如何快速查找出大key?
在缓存分析中有hotkey和bighey,bigkey会打一个RDB快照,从RDB快照中的后台任务去把RDB做遍历找出大key。这是一种离线分析方式。另外也有正在开发的在线实时的大key的定位,即将上线。
Q10. Redis 6.x适合生产环境吗?
Redis6.0有很多新的特性。6.0在阿里云上已经跑了很长时间了,在生产环境上是没有什么问题的,但是多IO并没有去支持。因为社区实现多IO的时候,虽然有多线程去做网络IO,但是它并不是IO和worker是并行的,而是由worker把主线程分发,等所有的线程IO执行完之后,再进行下面的步骤。这让容易造成CPU把整个机器跑满。所以多IO这个特性并不建议再生产环境上使用。