Redis学习历程(一) 一文了解 Redis

一、Redis是什么?

Redis是一个以内存作为存储的 NoSQL 型数据库。以是C语言开发并遵从BSD协议,常见用于数据库、缓存、消息中间件等。

优点:

  • 读写速度非常快:支持并发10W QPS。
  • 单进程单线程:是线程安全的,采用IO多路复用机制。
  • 丰富的数据类型:支持字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。
  • 支持数据持久化:可以将内存中数据保存在磁盘中,重启时加载。
  • 主从复制,哨兵,高可用。
  • 作分布式。

Redis为何这么快?

  • 完全基于内存,绝大部分请求是纯粹的内存操作,非常迅速,数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度是O(1)。
  • 数据结构简单,对数据操作也简单。
  • 采用单线程,避免了不必要的上下文切换和竞争条件,不存在多线程导致的CPU切换,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有死锁问题导致的性能消耗。
  • 使用多路复用IO模型,非阻塞IO。

二、支持的数据类型

在聊数据类型之前,我们先了解redis是如何表示数据类型的?如下图:
Redis学习历程(一) 一文了解 Redis
redis内部使用一个redisObject对象来表示所有的key和value。如上图所示:type表示一个value对象具体是何种数据类型,encoding是不同数据类型在redis内部的存储方式。
例如:type=string表示value存储的是一个普通字符串,那么encoding可以是raw或者int。

五种数据类型:

  1. string:以 key=>value方式存储,是二进制安全的,所以 string 类型可以包含任何数据,比如jpg图片或者序列化的对象。string 类型的值最大能存储512M。常见命令:set、get。
  2. Hash:hash 是一个 string 的 key 和 value 的映射表,所以特别适合存储对象。常用命令:hget、hset、hgetall等。
  3. list:简单的字符串列表,按照插入顺序排序。常用命令:lpush、rpush、lpop、rpop、lrange(获取列表片段)等。
  4. set:string类型的无序集合,通过hashtable实现的。set中的元素是没有顺序的,而且是没有重复的。常用命令:sdd、spop、smembers、sunion等。
  5. zset:string类型元素的集合,且不允许重复的元素。是有序的 额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。

三、redis-缓存问题

雪崩

含义:同一时间大面积 key 失效。一般特指热门数据,大范围失效,然后大量请求直接查询DB。导致数据库崩溃。

应对方法:

  1. 生成 key 时候有效期随机生成,避免同时过期。
  2. 如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效。
  3. 永不过期,数据更新时候更新缓存。
穿透

含义:穿透是指缓存和数据库中都没有的数据,而用户不断发起大量请求,直接查崩溃DB。一般是不合法的用户(黑客)攻击。

应付方法:

  1. 程序层过滤,做参数校验。
  2. 使用redis 布隆过滤器(Bloom Filter)。原理:利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查DB刷新KV再return。
击穿

含义:类似雪崩,不同之处在于特指一个热点 key,失效。在这个 key失效瞬间,大量的请求直接捅到数据库。所以叫缓存击穿。

应对办法:

  1. 数据永不过期。

四、淘汰策略

策略 备注
volatile-lru 从已设置过期时间的KV集中优先对最近最少使用(less recently used)的数据淘汰
volitile-ttl 从已设置过期时间的KV集中优先对剩余时间短(time to live)的数据淘汰
volitile-random 从已设置过期时间的KV集中随机选择数据淘汰
allkeys-lru 从所有KV集中优先对最近最少使用(less recently used)的数据淘汰
allKeys-random 从所有KV集中随机选择数据淘汰
noeviction 不淘汰策略,若超过最大内存,返回错误信息

备注: 文中部分图片、文字来源网络。