redis简介

Redis(RemoteDictionary Server ),即远程字典服务,是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

redis是一个key-value存储系统,支持存储的value类型包括string(字符串)、list(链表)、set(集合)、zset(sortedset--有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

业务场景

redis

组件版本:

redis:5.0.3

节点架构:

3主3从、6主机

1. 问题描述

某业务系统采用rediscluster架构,一批业务数据采用string类型设置过期时间key,业务部分过期key未删除,在redis集群里查找该key存在产生数据错误的故障。

2. 结构及详细说明

Redis集群大致架构图:

一组RedisCluster是由多个Redis实例组成,官方推荐使用6实例,其中3个为主节点,3个为从结点。一旦有主节点发生故障的时候,RedisCluster可以选举出对应的从结点成为新的主节点,继续对外服务,从而保证服务的高可用性。

对于客户端来说,如何知道对应key是要路由到哪一个节点的那?这里RedisCluster把所有的数据划分为16384个不同的槽位,可以根据机器的性能把不同的槽位分配给不同的Redis实例,对于Redis实例来说,他们只会存储部门的Redis数据,当然,槽的数据是可以迁移的,不同的实例之间,可以通过一定的协议,进行数据迁移。

fc92d8feb63ef5318334d0efc491bf9a.png

3. 问题定位

通过对提供的部分key在集群里查看状态为未删除,然后查看了业务设置过期时间的代码看无问题,如下:

0da5471f0c7a746d3ee9c35811ccad1c.png

通过对redis集群状态检查、槽数量、epoch等检查,redis集群状态正常,如下:

402b202f2c87dfd6746321ffc7206322.png

软件层检查后,再对主机linux层检查内存出现异常主要在swap层,趋势图如下:

acf87c4072bb26b8dc37d3721c96f0f4.png

swap快速增长

可判断由于业务数据量增长导致内存、swap增长,由于部分数据进入swap后导致部分key过期后未删除

4. 解决过程

从问题定位来看,解决方法有几种:

  1. 扩容内存使数据不占用swap并重启redis集群。

  2. 判断数据的重要性,可关闭redis本身的持久化,避免持久化过程中占用内存,进而占用swap。

  3. 扩容节点及增加主机、增加主节点来分散数据使单个节点内存占用量减少。

均衡当时的资源情况及数据重要性,决定采取第一种方法扩容内存6台主机从48G扩容到64G。

通过扩容内存后结合业务进行几天的观察后swap得到有效得控制,swap趋势图如下:

1c111300039bd616a250beb180bddb5a.png

后续业务未发生过期key未删除的情况

   总   结    

1、redis如果占用了swap,可能会导致各种问题(如之前过期key未删除等),建议在搭建环境时尽量统计业务数据量根据数据量来设置内存大小、并安装linux系统时关闭swap。

2、由于该redis开了持久化,在持久化过程中会占用当前主机内存,所以建议在开启持久化的时候建议主机内存的大小是redismaxmemory大小的的2倍以上。

3、redis集群一般建议多主机多节点,单节点内存不超过maxmemory20G。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐