答疑汇总Day1 走进Redis
https://developer.aliyun.com/article/782794
答疑汇总Day2 Redis开发实操之春运迁徙页面
https://developer.aliyun.com/article/782795
答疑汇总Day3 Redis的运维实战
https://developer.aliyun.com/article/782907
答疑汇总Day4 Redis的开发规范和常见问题
https://developer.aliyun.com/article/782909
答疑汇总Day5 Redis架构及介质选择指引
https://developer.aliyun.com/article/782910
答疑汇总Day6 Redis的高并发实战:抢购系统
https://developer.aliyun.com/article/783068
答疑汇总Day7 Redis的生态
https://developer.aliyun.com/article/783125
【开营第一课,走进Redis】
课程讲师:中科院计算所副研究员,蒋德钧
答疑讲师:仲肥,阿里云NoSQL内核工程师;Redis Core Team member
课程内容:Redis的整体架构,主要数据结构,以及支撑其高性能、高可扩展的关键技术机制。
答疑汇总:特感谢班委@邱谦 同学
Q1. Redis的线程模型是怎么单线程支持高并发的?
首先有个概念,并发和并行是不一样的。并行是指同一时间做很多事情,并发是指同一时间有多个请求。Redis的高并发指的是指很快地处理并发过来的请求,具体实现主要是依靠Linux操作系统。Redis本身的工作线程是单线程的,需要顺序地从网络读取数据,分析数据后执行,再把结果返回给客户端,都是在同一个线程去做的。这些客户端是如何激活的呢,主要是Redis用了操作系统提供的epoll(I/O多路复用技术)。
Q2. 给Redis增加CPU核心会没有性能提升吗?
在4.0之前,Redis的工作线程只有一个。正常情况下2-3核是够用的,添加更多CPU核心对于主线程来说确实是没有太大的效果的。
在6.0开始,Redis也开始支持多线程了,但处理用户请求还是一个线程,所有的请求在从操作系统获取过来还是串行地执行的。但网络这一块是多线程的,读网络和写网络是多线程。主线程从epoll里面收割事件,拿到所有活跃时间后,分发给I/O线程,接着再有主线程做收集,再执行(执行的过程也是单线程串行),再将结果分发给I/O线程。整个过程是“分-总-分”的模式。网络I/O在读写网络的时候是可以多线程并行的,但是执行逻辑还是要串行执行的。在这个时候给Redis分配多个CPU核心,性能是会提升上去的。
Q3. Redis和Memcached对比?
Redis可以当作Memcached的超集,Memcached本身就支持简单的key-value,比如String。Redis在大部分场景都可以覆盖Memcached。但是有一点,Memcached有版本的概念,有的操作是Redis的社区版是不支持的。如果大家想尝试这种操作的话,阿里云有Redis有企业版,Redis在4.0之后支持Module,阿里云开发了TairString等Module。
Q4.能把Redis直接当作持久化的DB吗?
主要看业务场景。如果只考虑单机,Redis本身提供AOF操作,且AOF可以配置fsync什么时候调用。一种是Redis不主动做fsync,如果Redis挂掉后,完全依赖操作系统。另外一种是每秒调用一次fsync,如果在极限情况下宕机,有可能丢一秒钟的数据。还有一种叫always,每次写AOF后都会主动调用fsync,可以严格保证Redis数据可以异步地写到磁盘上,但always对性能有一定影响。
主从版要复杂一些,虽然有fsync可以保证数据全都落盘,但主备Redis目前还不行,因为它是异步进行复制的,在实际操作上有可能会丢失一些数据。如果对小概率的丢失数据的场景能够容忍,还是可以当作持久化DB的,如果无法容忍这种情况,最好Redis还是作为缓存来使用。
Q5.Redis数据同步有哪些方案呢?
社区版本身有很多开源工具基于Redis的主从复制协议开发一些同步方案,简单地说,主从同步是没什么问题的,但是跨域的话,因为Redis的主从同步都是在内存里进行的,没有持久化。如果数据通道一旦断开,做同步就比较消耗时间和消耗资源。如果想跨域同步,建议还是自己带一套额外的中间件来做,比如从云端拉数据,再推到目的端。
Q6.请问Redis不设置密码时为什么会被挖矿,是因为有安全问题吗?
如果Redis不设置密码,所有人都可以访问,这时候有些操作是有可能获取到你的整机的执行权限,所以大家在运维Redis的时候一定要注意设置密码,云上都是强制必须设置密码的。
Q7.购买阿里云Redis集群的时候,对于4分片16G的配置,对于可用的内存存储是4G还是6G?这个分片越多访问速度越快还是高可用越稳定?
云上的配置通常是写几分片几G,比如4分片16G是指4个分片,每个分片16G,总共的可用内存就是4*16G,这是一个集群整体的可用内存情况。但它毕竟是分片的,所以数据是存储在不同的分片上面,比如A算出来Hash的结果,B算出来Hash的结果,有可能是分配在不同的分片上的,需要注意存储的倾斜。一般来讲,随机分布是不会出现很明显的倾斜的。
Q8.线上环境的redis 出现过2次数据全部丢失,请问除了手动flushdb的情况,还有什么情况回导致数据全部丢失呢?
如果实例没有发生过宕机,有可能就是手动flushdb造成的情况。如果出现宕机,且没有开数据持久化,有可能数据就全部丢了。
还有一种极端情况,虽然Redis有maxmemory这种设置,但是maxmemory指的是运行时可用的内存,并不是数据的内存。如果在实际运行中,耗费的内存已经超过一个G,可能会触发evict逐出,如果数据的设置又满足逐出策略的话,也是有可能发生数据丢失的。
Q9.Redis6.0后请求并发,是否保证顺序呢?
从单个链接上来看,即便时IO多线程,也是串行的。一个连接也是读网络,执行,返回数据,执行下一个命令,返回数据......从多个连接的情况来看,比如连接A B C,他们的读写是可以并行的,所以不用担心一个客户端是否可能乱序。
Q10.Redis不同的数据类型操作的时间复杂度都是O(1)吗?
Memcached都是O(1),但Redis不是,有很多数据类型,O(n)和O(logn)都是比较多的。
Q11.Redis的操作延迟在百纳秒/微妙级别,但是考虑到网络上的耗时,同机房可能在1~3毫秒,从客户端角度来说,这个百纳秒的性能是体现不出来的吗?
是的。性能分两个方面,吞吐和时延。网络本身的物理时延没有办法避免,但吞吐如果有多个客户端同时访问,吞吐上是可以达到很高的并发量的。
Q12.大小达到多少才算是bigkey?
①本身的数据长度,通常千以上的级别就是比较大的。
②本身的体积,也就是占用的内存,Redis默认最大上限是512MB。