redis
是一个非关系型内存数据库, 可以存储5种不同类型的值之间的映射
Redis
是C语言开发的一个开源的高性能键值对(key-value)的内存数据库,可以用作数据库、缓存、消息中间件等
redis
支持的5种不同数据结构类型,(string)字符串
, (list)列表
, (set)集合
, (hash)散列表
, (zset)有序集合
redis
支持两种不同的数据持久化方式, 一种方法叫快照
(它可以将存在于某一时刻的所有数据都写入磁盘), 另一种叫只追加文件
(它会在执行写入命令时,将被执行的命令复制到磁盘里面), 这两种方法即可以同时使用,又可以单独使用,
redis
快照模式持久化数据,如果系统崩溃,用户将丢失最近一次生成快照之后更改的所有数据, 因为只需要copy当前redis
中的数据到磁盘中,不额外占用磁盘空间,可以节约磁盘空间便于恢复
redis
只追加文件(AOF
)模式来持久化数据, 能保证丢失数据的时间窗口降低至1秒(甚至不丢失任何数据),但随着redis
的不断运行, AOF
文件体积不断变大这会占用大量磁盘空间,并且在恢复数据时也会因为AOF
文件过大导致恢复速度缓慢, 同时该模式也会对redis
的性能造成影响, 因为需要频繁的将写命令同步到AOF
文件中
redis
可以根据配置文件指定的持久化方式自动触发备份,也可以通过客户端发送命令bgsave
或者save
来手动触发备份
redis
采用单线程串行方式执行事务,可以避免锁的开销,事务冲突等问题,但是其吞吐量上限是单个CPU
核的吞吐量, 不能很好的应用CPU
的多核性能,redis
也不支持交互式的多语句事务
redis
支持主从复制特性, 不支持主主复制, 在redis
中从服务器也能拥有自己的从服务器并由此形成主从链
redis
的(set)集合
和(list)列表
的区别, 列表可以存储多个相同的字符串, 而集合的值是不能重复的, 集合使用无序方式存储元素,所以集合不能像列表那样将元素推入集合的某一端, 或者从集合的某一端弹出元素
redis
中集合支持交集
,并集
,差集
计算
有序集合的键称为成员(member), 每个成员都是各不相同的, 而有序集合的值称为分值(score), 分值必须为浮点数
有序集合是redis
里面唯一既可以根据成员访问元素, 又可以根据分值的排列顺序来访问元素的结构
redis
的字符串类型提供了很多处理操作方法, 这些操作方法类似于php
字符串函数库的API
,因为redis
本质上就是在直接操作内存里面的数据,所以redis
在数据处理方面相比传统数据库可以提供很大的灵活性, 这也是它的优势之一
在redis
里面,多个命令原子的执行指的是, 在这些命令正在读取或者修改数据的时候,其它客户端不能读取或者修改相同的数据
redis
发布订阅功能(pub/sub)
的缺点,无法有效保证数据的可靠传输, 如果客户端在执行订阅操作的过程中断线,那么客户端将丢失在断线期间发送来的所有消息,, 如果能够承担可能会丢失一小部分数据的风险,那么可以使用该功能
redis
排序操作sort
指令可以针对redis
的5种数据结构进行排序操作,sort
排序操作类似于MySQL
中的order by
redis
的基本事务需要用到multi
命令和exec
命令, 这种事务可以让一个客户端在不被其它客户端打断的情况下执行多个命令,和关系型数据库那种可以在执行过程中进行回滚的事务不同, 在redis
里面被multi
命令和exec
命令包围的所有命令会一个接一个的执行, 直到所有命令执行完毕为止, 当一个事务执行完毕后,redis
才会处理其它客户端的命令
redis
事务执行的过程,当redis
客户端接收到multi
命令时,会将这个客户端之后发送的所有命令都放在一个队列里,直到这个客户端发送exec
命令为止,然后redis
会在不被打断的情况下,逐一执行队列里面的命令
redis
可以对键设置过期时间,对于集合
,散列
,列表
,有序集合
这样的容器来说, 键过期命令只能为整个键设置过期时间,而没办法为键里面的单个元素设置过期时间
ttl
命令可以用来查看指定键距离过期还有多长时间
redis
主从模式, 从服务器在进行同步时, 会清空自己的所有数据, 所以从服务器与主服务器进行初始连接时, 从服务器中原有的数据都将丢失
一次性发送多个命令, 然后等待所有回复出现的做法通常被称为流水线
( pipelining ), 它可以减少客户端与redis
服务器之间的网络通信次数来提升redis
在执行多个命令时的性能
虽然redis
是单线程,但是当多个客户端访问时,每个客户端都会有一个线程。客户端访问之间存在竞争,redis
里面命令的执行是由一个线程来完成的。比如set
,get
。每执行一个命令都需要客户端来竞争,所以可能出现并发问题,但如果你的命令希望把一组命令执行的结果作为整体,要么全部成功,要么失败,就必须用锁,或者事务
Redis
单线程,指的是"其网络IO和键值对读写是由一个线程完成的",也就是说,Redis
中只有网络请求模块和数据操作模块是单线程的。而其他的如持久化存储模块、集群支撑模块等是多线程的。
redis
的watch
命令只会在数据被其他客户端抢先修改了的情况下通知执行了这个命令的客户端,而不会阻止其他客户端对数据进行修改, 所以这个命令被称为乐观锁
redis
实现分布式锁指令setnx
(set if not exists), 释放锁使用del
指令删除,为了保证不成为死锁最好使用expire
指令为锁加一个过期时间,这种组合指令因为不是原子性的操作并不保险,所以可以通过set
指令的扩展参数来达成相同的效果,且是原子性的操作set(key, value, nx=true, ex=5)
使用redis
的list
做消息队列时,当队列为空了,客户端就会陷入pop
的死循环,这会浪费服务器的资源,通常我们使用sleep
来解决这个问题,让线程睡眠一会,但睡眠会导致延迟增大, 这个时候可以采用blpop/brpop
以阻塞方式读取list
,阻塞读在队列没有数据的时候, 会立即进入休眠状态, 一旦数据到来, 则立即醒过来.消息的延迟几乎为0
redis
的位图可以满足一些存储bool
型数据的需求,位图最小的单位是bit, 每个bit的取值为0或者1,位图不是特殊的数据结构,它的内容其实就是字符串可使用set/get
或者getbit/setbit
指令来操作
redis
HyperLogLog
数据结构可以实现类似于set
集合一样的去重功能,它适合用来做大数据的去重计数,因为它占用的空间非常小(大约12KB内存空间)
, 缺点是它统计数据条目总数时会存在误差(标准误差0.81%)
,而且也无法判定一个元素是否存在于HyperLogLog
中
redis
布隆过滤器可以把它理解为一个不怎么精确的set
结构,当你使用它的contains
方法判断某个值是否存在时,布隆过滤器对于那些已经见过的元素肯定不会出现误判,它只会误判那些没有见过的元素,也就是说,如果一个值已经加入到布隆过滤器中了,那么判断这个值是否存在时不会出现误判,如果这个值没有加入到布隆过滤器中那么可能会出现误判的情况, 可以通过自定义配置来设置redis
布隆过滤器的误判率(error_rate)
,误判率越小意味着需要的存储空间越大
redis
的GeoHash
可以用来实现类似摩拜单车的附近的mobike
, 美团和饿了么的附近的餐馆这样的功能, 在使用Geo
进行查询时,我们要时刻想到它的内部结构实际上只是一个zset
redis
查看存储的key可以使用指令keys
来实现, 但是keys
指令会把所有的匹配项都查询出来, 当存储的key
非常多时, keys
指令会导致redis
服务卡顿其它指令延迟等候执行, 这种情况可以使用scan
指令来代替keys
,scan
可以添加offset,limit
等条件参数来限制提取匹配结果的条目数
使用redis-cli
的“--bigkeys
”选项查找大Key
查看redis
配置和环境信息命令info
当redis
占用的内存超过了maxmemory
时数据的淘汰策略
方式 | 描述 |
---|---|
volatile-lru | 从设置过期时间的数据集中挑选出最近最少使用的数据淘汰。没有设置过期时间的key不会被淘汰 |
volatile-random | 从已设置过期时间的数据集中任意选择数据淘汰 |
allkeys-lru | 从数据集中挑选最近最少使用的数据淘汰 |
no-enviction | 不会继续服务写请求,读请求可以继续进行( 默认的淘汰策略 ) |
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。