简介
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
数据结构
- String:
二进制
安全的字符串。
-
应用举例
:MySql的缓存层、视频播放量累加计数、共享Session、限速。
- Lists: 按
插入顺序排序
的字符串元素的列表。他们基本上就是链表(linked lists)。
-
应用举例
:栈(lpush+lpop)、队列(lpush+rpop)、有限集合(lpush+ltrim)、消息队列(lpush+brpop)、。
- Sets:
不重复
且无序
的字符串元素的无序集合。
-
应用举例
:标签。
- Sorted Sets:
不重复
且有序
的字符串元素的有序集合。
- 类似Sets,但是每个字符串元素都关联到一个叫score浮动数值(floating number value)。
- 里面的元素总是通过score进行着排序,所以不同的是,它是可以检索的一系列元素。
- 例如你可能会进行
范围查询
:给我前面10个或者后面10个元素。 -
应用举例
:消息重试、排行榜。
- Hashes: 由field和关联的value组成的散列表。field和value都是字符串的。这和Ruby、Python的hashes很像。
-
应用举例
:对象信息(对象的每个属性对应一个键)。
- Bit arrays (或者说 simply bitmaps): 位图。通过以一个比特位来表示
key
对应的value
是0还是1。
- 并不是一种真实的数据结构,而是将String值当做比特来处理。
- 由于字符串是二进制安全的大对象,其最大长度是512MB,因此位图适合设置2^32个比特位。
- 通过特殊的命令,你可以将 String 值当作一系列 bits 处理:
- 可以设置和清除单独的 bits;
- 可以数出所有设为 1 的 bits 的数量;
- 可以找到最前的被设为 1 或 0 的 bit,等等。
-
应用举例
:存储用户的在线状态:在线=1,离线=0。
- HyperLogLogs: 基数统计。是一种基于概率的数据结构,用于估算一个集合中指定元素的个数。
- HyperLogLog 在 Redis 中每个键占用的内容都是 12K,理论存储近似接近 2^64 个值。
- 优势在于:这个结构可以非常省内存的去统计各种计数。
- 缺点在于:估算的基数并不一定准确,是一个带有 0.81% 标准错误的近似值。
-
应用举例
:注册 IP 数、每日访问 IP 数、页面实时UV)、在线用户数等。
- Geospatial: 地理位置。将给定的空间元素(纬度、经度、名字)添加到指定的键里面。
- 这些数据将会存储到有序集合中,以方便后续的半径查询等操作。部分可进行的操作有:
- 通过
GEOPOS
从键里面返回所有给定位置元素的位置(经度和纬度)。 - 通过
GEODIST
返回两个给定位置之间的距离。 - 通过
GEORADIUS
以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
-
应用举例
:地图位置。
回收策略
当Redis被当做缓存来使用,当你新增数据时,让它自动地回收旧数据是件很方便的事情。
LRU是Redis唯一支持的回收方法,所谓LRU即:Least Recently Used,最近最少使用算法。
Redis的maxmemory
指令用于将可用内存限制成一个固定大小。Redis的maxmemory
指令用于将可用内存限制成一个固定大小
maxmemory 100mb
设置maxmemory
为0代表没有内存限制。对于64位的系统这是个默认值,对于32位的系统默认内存限制为3GB。
当maxmemory限制达到的时候Redis会使用的行为由 Redis的maxmemory-policy配置指令来进行配置。
以下的策略是可用的:
- noeviction:返回错误。
- allkeys-lru:对全部键,尝试回收最近最少使用(LRU)的键。
- volatile-lru:对在过期集合的键,尝试回收最近最少使用(LRU)的键。
- allkeys-random:对全部键,尝试回收随机的键。
- volatile-random:对在过期集合的键,尝试回收随机的键。
- volatile-ttl:对在过期集合的键,优先回收存活时间(TTL,Time To Live)较短的键。
策略选择举例:
- 如果你想要通过创建缓存对象时设置TTL值,来决定哪些对象应该被过期,可以选择:volatile-ttl。
- 如果你是循环访问,所有的键被连续的扫描,或者你希望请求分布正常,可以选择:allkeys-random。
- 如果你不确定选择什么,可以选择:allkeys-lru。
持久化
Redis 有两种持久化方案,RDB (Redis DataBase)和 AOF (Append Only File)。
RDB
- RDB 是 Redis 默认的持久化方案。
- 在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中,即在指定目录下生成一个dump.rdb文件。
- Redis 重启会通过加载dump.rdb文件恢复数据。
- RDB配置方式(redis.conf):
## save 指定时间间隔内 执行指定次数的更新操作
## 如果900秒内有1次更新操作,或者300秒内有10次更新操作,或者60秒内有10000次更新操作,则将内存数据持久化至磁盘。
save 900 1
save 300 10
save 60 10000
## 指定本地数据库文件名
dbfilename dump.rdb
## 指定数据库存放陌路
dir ./
## 默认开启数据压缩
rdbcompression yes
- 可以手动通过SAVE(阻塞持久化, 只管保存快照,其他的等待)和BGSAVE(异步非阻塞持久化)命令,让redis进行持久化操作。
- 工作方式:
- Redis调用forks,同时拥有父进程和子进程;
- 子进程将数据写入临时RDB文件;
- 当新RDB文件写入完成,替换掉旧RDB文件,删除旧RDB文件。
AOF
采用RDB方式,如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。
从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 。
AOF配置方式(redis.conf)
## 开启AOF
appendonly yes
## 指定本地数据库文件名
appendfilename "appendonly.aof"
## 指定更新日志条件
# appendfsync always
appendfsync everysec
# appendfsync no
从现在开始, 每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。
这样的话, 当 Redis 重新启时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。
三种AOF更新方式:
- always:每次发生数据变化会立刻写入到磁盘中。性能差、数据完整性高。
- everysec:每秒异步记录一次。默认配置。性能好。
- no:不同步。
缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。
针对AOF文件很大的问题,Redis提供了重建rebuild机制,
总结
- Redis默认开启RDB持久化方式。
- RDB性能较高,但数据一致性和完整性相对差;AOF数据一致性和完整性相对好,但性能较低。
- 如果Redis只做缓存,可以关闭持久化。
- 如果Redis做持久化,建议RDB和AOF都开启。
参考