内容提要:
- 1000 个线程压测时 Redis Incr 出现错误,就是 Timeout,怎么排查?有什么好的经验分享?
- 批量查寻是用 MGET 好还是 Hash 更好,Hash的性能瓶颈是多少,达到多少个 Key 或者多大容量后性能急剧下降?如果需要大批量的查例如 1000 个 Key,用什么方案更好?MGET 在集群模式下的实现方式是什么,怎么知道某个 Key 在哪个集群分片上?Redis 最大并发大约支持 5~10 万并发,假设现在有 20 万或者 50 万并发该怎么办?
- Redis 分布式集群的几种解决方案,哨兵等方案结合生产环境经验的区别、优劣是什么?
- jedispool 链接对象无法释放,这个怎么办?代码写了在 finally 里面也执行了,然后看客户端连接数越来越多,最后项目挂了怎么办?
- 讲下 Redis 和数据库同步;还有 Redis 的几个大问题:缓冲击穿和缓冲穿透、雪崩问题、hyperloglog slowqery 实现原理?
- 缓存穿透:如果是恶意攻击,那么存在访问的数据数据库不存在且数据各不相同,如何避免这一情况?
- 讲下 Redis 持久化?
- 能不能讲下实际应用场景里怎么使用?
- 无论是 Win 或 Linux 都有此现象,服务器 Redis 3.x,客户端 Hiredis,在客户机与服务器间网络不稳定的情况下,客户机可能收不到服务器推送来的消息,以及客户机发布消息时会塞死。是否能提供相关解决经验?
- 所列 Key 操作的实际商业运用(具体运用)场景有哪些?举几个详细的例子可以吗?
- 请教下 Redis 的连接数用什么命令监测?
- Redis 的配置要主要哪些参数调优?
- 一个转行的本科生即将干 Java 开发,想考一个本行业的研究生,有什么大学和专业和书本和实操推荐?
- 登录 Redis 出现提示,要求密码 NOAUTH Authentication required 有什么办法可以免密登录?
- 有没有在生产环境下用 Redis 做持久化存储的例子?一般怎么配置 AOF 和 RDB?在高并发并且尽量少数据丢失的情况下有哪些优化手段?
- 哨兵模式下 Client 是随机挑选其中一个哨兵发送 Request 吗?那么如果这个哨兵 Process 挂了会怎样?
- Redis 集群很多个 Redis 的话,是把多个 IP 全部写到代码里面,那会不会导致压力不均衡?
- 要开始使用 Redis 的时候,如何预估生产环境需要多少计算资源(Cluster 机器数量、内存、CPU、硬盘空间、Slave 数量等)?有没有一些通用的经验?
- AOF 和 RDB 配合着用,恢复数据哪个为主?
- 假如内存 8G 的话,Redis 既然是运行在内存中,那 Redis 最大能存多大数据?
问:1000 个线程压测时 Redis Incr 出现错误,就是 Timeout,怎么排查?有什么好的经验分享?
答:这个我们之前真的遇到过,是商城首页获取数据的时候导致 timeout。不过后来发现不是因为并发量高,是链接忘记释放了。
你的这种情况我建议:
- 先查看一下与 Redis 服务器相连的配置项是否正确,比如说 Maxidle、Maxwait、MaxActive 等。
- 然后看一下压测服务器以及 Redis 服务的资源情况如何,常见的 CPU、内存、磁盘、Load 等。
- 重点看一下 Redis 的连接数是什么情况,是不是连接数过多,导致超时,对比一下最大连接数和当前连接数。
问:批量查寻是用 MGET 好还是 Hash 更好,Hash的性能瓶颈是多少,达到多少个 Key 或者多大容量后性能急剧下降?如果需要大批量的查例如 1000 个 Key,用什么方案更好?MGET 在集群模式下的实现方式是什么,怎么知道某个 Key 在哪个集群分片上?Redis 最大并发大约支持 5~10 万并发,假设现在有 20 万或者 50 万并发该怎么办?
答:从性能上考虑 建议使用 Hash。 而且在集群模式下 MGET 批量查询其实是没办法特别好的支持的。至于 Hash 批量获取的性能瓶颈具体数值我这边没有做过具体压测,所以没办法给出准确的数值。集群模式不同版本对于 MGET 指令的支持不同。 在集群 3.0 版本,是不支持 MGET 的, 在集群 4.0 版本仅支持相同 Slot,Key 不能保证在相同 Slot 还是没用。有些 Redis 的客户端,对 MGET 指令做了一些上层的封装,但性能不是很好。
至于提高集群并发能力我觉得这个是非常好的问题,从两个个方面考虑:
- 从垂直方向考虑,就是优化 Redis 单服务的并发能力,这里面可以考虑 Redis 的持久化开销、数据存储 IO 开销、指令使用正确与否、服务器的硬件配置(内存,磁盘,CPU 等)、链接参数的配置优化。
- 从水平方向思考,不管怎么优化,垂直方向能力都是有限的,因此需要考虑水平扩展,这时候就需要搭建集群模式,同时也要思考业务的拆分。基于业务来拆分不同的集群,然后也要保证集群的平稳扩容相关的操作。
问:Redis 分布式集群的几种解决方案,哨兵等方案结合生产环境经验的区别、优劣是什么?
答:在业务发展初期,我们采用的主从模式,简单直接。但这个场景是在业务发展初期,公司平台能力建设还没有完善。到了后期就不行了,多条业务线,每个业务线的流量也比较大。现在面临两个选择:大家每个业务线都建立一个主从,这很明显在资源方面把控不住。有些流量特别小的业务线,也要重复建设,而且运维成本也在重复。
所以后期就直接选择了集群模式,集群模式统一由中间件平台组管理,而且不同的业务线进行集群的隔离。保证了业务之间不受彼此影响,但集群的维护在同一个平台团队,保证了运维成本的统一,不会技术性质的重复建设。这是从实际的生产经历来说这个问题,具体集群模式上的技术点区别,可以参考咱们的文章,里面有详细的介绍。
问:jedispool 链接对象无法释放,这个怎么办?代码写了在 finally 里面也执行了,然后看客户端连接数越来越多,最后项目挂了怎么办?
答:这个问题我之前没有遇见过。之前碰到的一个问题是:忘记释放链接,导致链接数过大。你这种我还真没有遇见过,不过我建议看一下他们客户端释放链接的源代码,看看在释放链接的代码实现上是否存在多步操作。导致客户端的释放链接的方法没有正确的执行,如果还是找不到原因,你再联系我,我帮你一起看看源代码。
问:讲下 Redis 和数据库同步;还有 Redis 的几个大问题:缓冲击穿和缓冲穿透、雪崩问题、hyperloglog slowqery 实现原理?
答: Redis 和数据库同步这个问题,分很多场景。
先说同步方式:
- 查询同步,就是业务先访问缓存,如果缓存没有,就访问数据库,然后也同步到缓存,同步一段时间。
- 异步同步,可以利用异步消息或者 MySQL 的 Binlog 消息,来进行缓存的同步,也叫做异步更新。
- 定时同步,也可以采用定时脚本的方法进行刷新同步,也叫做预加载。
然后是数据一致性部分:
对于数据一致性比较高的场景,在写操作的时候进行双写操作,如果数据库数据有修改,就使用异步消息达到最终一致性的要求,或者通过异步消息来 Check 数据之间的一致性。数据一致性部分,因为是网络之间的交互很难达到强一致性,我们只能通过最终一致性来保证数据的准确。
最后,数据更改方面,比较建议使用直接将缓存数据删除,然后再到数据库中同步的方式。缓冲击穿和缓冲穿透、雪崩问题相关的内容文章中都有介绍,大家可以先去看看介绍的内容,文章有不清楚的地方,咱们再一起讨论一下,咱们在这里就不再重复了。
对于 hyperloglog 说的简单点就是用数据准确性来换区内存空间使用效率,节省内存使用率。比较常见的就是统计页面访问 UV 数据,需要去重但准确性要求没有那么严格的数据比较适合 hyperloglog 形式来记录。
问:缓存穿透:如果是恶意攻击,那么存在访问的数据数据库不存在且数据各不相同,如何避免这一情况?
答:这种可以通过流量监控,或者流量分控来处理。恶意攻击流量通过这些手段还是比较方便检测出来。
问:讲下 Redis 持久化?
答: Redis 持久化机制分为 RDB AOF 两种机制,他们彼此的优缺点也比较明显。咱们文章中有详细的介绍,具体内容可以查看文章的第六大部分面试题目第六题,有详细的介绍。
问:能不能讲下实际应用场景里怎么使用?
答:实际代码可能会涉及到公司的业务实现,处于安全考虑不方便提供。如果有实现上的困难或者疑问可以直接提出来,咱们一起探讨技术实现方案。 文章中也介绍了很多业务真实场景的实现,可以参考一下。
问:无论是 Win 或 Linux 都有此现象,服务器 Redis 3.x,客户端 Hiredis,在客户机与服务器间网络不稳定的情况下,客户机可能收不到服务器推送来的消息,以及客户机发布消息时会塞死。是否能提供相关解决经验?
答:看一下 Hiredis 使用的是同步模式还是一部模式,如果使用的是同步模式,这类问题很容易出现,异步模式应该会缓解此类现象的发生。
同步模式如何解决?看一下超时相关的配置设置,确保一个安全的区域,保证系统不会因为网络问题导致阻塞。
问:所列 Key 操作的实际商业运用(具体运用)场景有哪些?举几个详细的例子可以吗?
答: EXISTS KEY 有时候会用于用户是否存在的判断,KEY 的设计要以用户唯一标识为值。
这种在进行分布式循环等待的时候使用过,具体的业务场景描述可能会比较复杂,简单来说就是商品库存的管理。其他的一些指令都是简单的操作, 配合其他指令来实现的。比如删除、修改之类的,用到的其实不多。
问:请教下 Redis 的连接数用什么命令监测?
答: Info Clients 就可以查看,这个比较简单在命令行端上直接输入指令就行了。
问:Redis 的配置要主要哪些参数调优?
答:比较场景的我们重点关注:
MaxActive:表示最大连接数。
MaxIdle:连接池空闲连接列表的长度限制。
IdleTimeout:空闲连接的超时设置,一旦超时,将会从空闲列表中摘除。
当然还有其他的常用配置项,比如说最大内存使用,缓存持久化配置参数等。
在参数配置的时候要考虑你的业务场景,是高并发还是相对低频的业务,根据实际的业务场景来进行配置就 OK 了。
问:一个转行的本科生即将干 Java 开发,想考一个本行业的研究生,有什么大学和专业和书本和实操推荐?
答:大学有很多,看你想去的地方。北京这边清华北大北航北邮都挺好的,上海那边复旦交大同济都挺好的。一般都是大家认为的好学校,但要有一个观点,那就是考研的难度远远低于高考。只要努力肯定没有问题。
至于书籍推荐,我觉得有好多。关于 Redis 的我建议直接看官网就行,中文的书籍其实大部分也都是基于官网的知识点,展开了一下给大家看。
专业这个我认为计算机科学与技术、计算机软件与理论这些都没有问题。因为到研究生的时候,会根据你导师的方向分配对应的工作的,所以考研一定要看清楚你选择的导师的方向。
问:登录 Redis 出现提示,要求密码 NOAUTH Authentication required 有什么办法可以免密登录?
答:通过修改配置项:protected-mode 可以实现,也要注意下你的 Redis 版本。
问:有没有在生产环境下用 Redis 做持久化存储的例子?一般怎么配置 AOF 和 RDB?在高并发并且尽量少数据丢失的情况下有哪些优化手段?
答:有点但是很少,一般 Redis 使用缓存提高性能比较多。持久化的话其实 Redis 的两个模式都有可能不同程度的偏差,而且 Redis 是内存数据读取,存储容量有限,其实对于持久化大数据量不是很方便,代价也比较高。 有一些业务使用的是 Tair 来进行持久化缓存的操作,你可以看一下 Tair 与 Redis 的区别。
一般怎么配置 AOF 和 RDB?这个可以随便搜一下配置文档,不难,在这里我们就不做详细的书写了,而且 AOF 和 RDB 配合使用,对于持久化的优化方面有很大的好处,可以考虑这个方案。
在高并发并且尽量少数据丢失的情况下有哪些优化手段?刚才说了 RDB 和 AOF 来配合使用,如果还需要更严格的手段,那么久需要使用异步消息验证机制、多重保障。或者直接写文件(比如存到 MySQL 里面等)。
问:哨兵模式下 Client 是随机挑选其中一个哨兵发送 Request 吗?那么如果这个哨兵 Process 挂了会怎样?
答:每个哨兵都会按照一定的频率定时的向集群中每个 Master 或者 Slave 服务器发送 Ping 命令,来监控服务器的运行状态。如果哨兵模式你配置的是单个哨兵,如果哨兵挂了就存在单问题了,可以配置多个哨兵彼此容灾。
咱们文章的图形画的比较简单,咱们参考一张哨兵模式的图形,可能就会更加容易理解。
问:Redis 集群很多个 Redis 的话,是把多个 IP 全部写到代码里面,那会不会导致压力不均衡?
答: Redis Cluster 集群模式,自动实现负载均衡的。哨兵其实就是一个监控或者容灾的作用,它下面实际的数据提供还是主从模式,所以如果是哨兵模式就不存在压力不均衡的模式了。
看咱们文章的图形,可以看到一些。
问:要开始使用 Redis 的时候,如何预估生产环境需要多少计算资源(Cluster 机器数量、内存、CPU、硬盘空间、Slave 数量等)?有没有一些通用的经验?
答:从几个方面考虑:
- 实际的存储容量方面,你需要考虑一下目前业务的数据量有多大,以及未来增量有多大,比如所我们存储的一个产品信息,一个产品信息是 10K 我要存 10000 万条,产品信息总量是多大,然后随着业务发展 产品的数量也会递增,我们是怎么满足这个增长预期的,我要预留多久的空间,比如说半年 然后计算出来你的容量。
- 根据业务的 QPS 能力,这个设计到压测了,根据业务的访问并发量,然后根据链路压测,测试出来大概的单机或者单集群的并发能力上线。然后,基于现实的 QPS 峰值来进行集群的搭建。至于硬盘、节点数量的,都是基于这上面两点的数据来考虑的。一般的经验是 5 倍的去思考,3 倍的去准备,当然 2 倍的去准备也 OK。
问:AOF 和 RDB 配合着用,恢复数据哪个为主?
答: RDB 是持久化的全量数据,AOF 主要是增量数据的持久化。
问:假如内存 8G 的话,Redis 既然是运行在内存中,那 Redis 最大能存多大数据?
答:这个最大存储的容量是你自己定义的,但是在业务场景下,注意不要有大 Value 的存储,会影响整个集群的 IO 性能。