Redis用途
Redis优缺点
- 优点:
- 快速:Redis使用内存存储数据,读写速度非常快。
- 多种数据类型:Redis支持多种数据结构,可以适应不同的应用场景。
- 丰富的特性:Redis支持事务、Lua脚本、发布订阅模式等高级特性。
- 可扩展性:Redis可以通过主从复制、哨兵模式和集群模式等方式实现高可用和横向扩展。
- 缺点:
- 内存限制:由于Redis使用内存存储数据,因此受到内存容量的限制。
- 持久化问题:Redis默认不会将数据持久化到硬盘,需要使用持久化机制来解决数据丢失问题。
- 单线程模型:Redis采用单线程模型,虽然可以通过多实例和多线程方式解决并发问题,但是并发能力相对较弱。
docker运行Redis
$ docker run -d -p 6379:6379 --name="local-redis" redis --requirepass 123456
Redis常用命令
String命令
-- $ set key value
set age 18
-- $ setnx key value
-- 如果key存在,value不存在,则赋值
-- 如果key存在,value存在,则不做处理
-- 如果key不存在,则添加key-value
setnx name Tom
-- $ setex key seconds value 设置key-value在seconds秒后失效value变为null
setex name 10 Lee
-- $ ttl key 查看key存活时间
ttl name
-- $ del key
del name
-- $ get key
get age
-- $ incr key 自加1
incr age
-- $ decr key 自减1
decr age
-- $ incrby key increment 将key对应的value自增increment
incrby age 10
-- $ mset k1 v1 k2 v2 k3 v3 ... 批量添加key-value
mset name Tom age 18 sex 1
-- $ mget k1 k2 k3 ... 批量获取key的value
mget name age sex
-- $ append key value 在key对应的value值上拼接value
append name ,World
-- $ setrange key offset value 从offset索引处开始逐字符串替换key所对应的value值
setrange name 6 Lee
Hash命令
-- $ hset key field value 将field-value放到Redis中,键为key
hset user name Lee
hget user name
-- $ hexists key field 判断key中的field是否存在
hexists user age
hdel user name
hincrby user age 10
-- $ hlen key 返回key中field的数量
hlen user
-- $ hkeys key 获取key下所有的field值
hkeys user
-- $ hvals key 获取key下所有的value值
hvals user
-- $ hgetall key 获取key下所有的field-value值
hgetall user
List命令
-- $ rpush key value 从右开始向key中添加value值
rpush name Lee
rpush name Tom
-- $ lpush key value 从左开始向key中添加value值
lpush name zhangsan
-- $ lrange key start stop 从左开始遍历key所对应的value值
lrange name 0 2
-- $ lpop key 删除key中最左侧的value并返回删除的value
lpop name
-- $ rpop key 删除key中最右侧的value并返回删除的value
rpop name
-- $ llen key 获取key所对应的value长度
llen name
-- $ linsert key before pivot value 操作key对应的value队列,在pivot值之前插入value值
linsert name before Lee Hello
-- $ linsert key after pivot value 操作key对应的value队列,在pivot值之后插入value值
linsert name after Lee World
-- $ lset key index value 操作key对应的value队列,修改索引为index的value值
lset name 2 Hello,World
-- $ lrem key count value 操作key对应的value队列,删除count个值为value的元素
lrem name 3 Tom
-- $ ltrim key start stop 操作key对应的value队列,截取start到stop内的元素作为value值
ltrim name 2 4
-- $ lindex key index 操作key对应的value队列,获取index索引下value的值
lindex name 2
Set命令
-- $ sadd key members[...] 向key中添加多个member元素
sadd name a b c
sadd name1 Tom Lee ZhangSan XiaoMing
sadd name2 XiaoLiu Tom Lee XiXi
-- $ smembers key 遍历key集合中的所有元素
smembers name
-- $ srem key members[...] 删除key集合中的多个member元素
srem name a b d
-- $ spop key count 随机删除key集合中的count个元素,并返回删除的元素
spop name 3
-- $ sdiff key1 key2 返回key2集合中没有的key1集合中的元素(差集) ZhangSan XiaoMing
sdiff name1 name2
-- $ sdiffstore key key1 key2 将key2集合中没有的key1集合中的元素放到key集合中
sdiffstore name name1 name2
-- $ sinter key1 key2 返回key1 key2集合的交集
sinter name1 name2
-- $ sinterstore key key1 key2 将key1 key2集合的交集放到key集合中
sinterstore name name1 name2
-- $ sunion key1 key2 返回key1 key2集合的并集
sunion name1 name2
-- $ sunionstore key key1 key2 将key1 key2集合的并集放到key集合中
sunionstore name name1 name2
-- $ srandmember key count 随机获取key集合中的count个元素
srandmember name 3
-- $ sismember key member 判断member元素是否在key集合中
sismember name Tom
-- $ smove key1 key2 member 将key1集合中的member元素移动到key2集合中
smove name1 name2 XiaoMing
ZSet命令
-- $ zadd key score member score member ... 按score排序将member元素添加到key集合中
zadd name 1 熊大 3 张三 5 王五 7 孙七 9 吴九 2 熊二 4 李四 6 赵六 8 周八 0 郑十
zadd name 1 熊大
zadd name 3 张三
zadd name 5 王五
zadd name 7 孙七
zadd name 9 吴九
zadd name 2 熊二
zadd name 4 李四
zadd name 6 赵六
zadd name 8 周八
zadd name 0 郑十
-- $ zincrby key increment member 将key集合中的member元素排名分数增加increment
zincrby name 10 郑十
-- $ zcard key 返回key集合中元素个数
zcard name
-- $ zrank key member 返回key集合中member元素的正序排名
zrank name 周八
-- $ zrevrank key member 返回key集合中member元素的倒序排名
zrevrank name 周八
-- $ zscore key member 返回key集合中member元素的分数
zscore name 郑十
-- $ zrange key start stop [withscores] 返回key集合中start到stop的元素并进行升序,withscores显示分数
zrange name 0 9 withscores
zrange name 0 -1 withscores
-- $ zrevrange key start stop [withscores] 返回key集合中start到stop的元素并进行倒序,withscores显示分数
zrevrange name 3 8 withscores
-- $ zrangebyscore key min max [withscores] 返回[min, max]分数范围内key集合中的元素(正序)
zrangebyscore name 3 7 withscores
-- $ zrevrangebyscore key max min [withscores] 返回[min, max]分数范围内key集合中的元素(倒序)
zrevrangebyscore name 7 2 withscores
-- $ zrem key member 删除key集合中的member元素
zrem name 郑十
-- $ zremrangebyscore key min max 删除[min, max]分数范围内key集合中的元素
zremrangebyscore name 3 7
-- $ zremrangebyrank key start stop 删除[start, stop]排名范围内key集合中的元素
zremrangebyrank name 3 7
-- $ zcount key min max 返回key集合中分数在[min, max]范围内的元素个数
zcount name 3 7
全局命令
-- 查看Redis中的key
keys *
keys *a*
-- 判断key是否存在
exists name
-- 为key添加过期时间
expire name 10
-- 取消key过期时间
persist name
-- 切换数据库,默认为0
select 2
-- 将key移动到指定数据库
move name 0
-- 随意返回一个key
randomkey
-- 修改name1为name0
rename name1 name0
-- 打印信息
echo Hi,Lee
-- 查看key个数
dbsize
-- 查看redis信息
info
-- 查看所有redis配置信息
config get *
-- 清空当前数据库
flushdb
-- 清空所有数据库
flushall
Redis事务
-- 开始事务
multi
-- 命令入队
sadd name "Tom" "Lee" "ZhangSan" "XiaoMing"
smembers name
-- 执行事务
exec
Redis持久化机制
RDB
-
手动触发
方式
save
同步阻塞主进程,只有等save完后成,才能进行新操作bgsave
fork的子进程,非阻塞,等执行完后会通知主进程,然后关闭子进程
-
自动触发
方式
save m n
在m
秒内数据集存在n
次修改时自动触发bgsave
命令
-
优点
:
- RDB是Redis数据的一个非常紧凑的单文件时间点表示。RDB文件非常适合备份。
- 例如,您可能希望在最近的24小时内每小时归档一次RDB文件,并在30天内每天保存一个RDB快照。这使您能够在发生灾难时轻松恢复不同版本的数据集。
- RDB非常适合灾难恢复,它是一个紧凑的文件,可以传输到远程数据中心或AmazonS3(可能是加密的)。
- RDB最大限度地提高了Redis的性能,因为Redis父进程要想持久化,唯一需要做的工作就是派生一个子进程来完成其余的工作。父进程永远不会执行磁盘I/O或类似操作。
- 与AOF相比,RDB允许使用大数据集更快地重新启动。
- 在副本上,RDB支持重新启动和故障切换后的部分重新同步。
-
缺点
:
- 如果您需要在Redis停止工作(例如停电后)的情况下将数据丢失的可能性降至最低,那么RDB就不好了。您可以在生成RDB的位置配置不同的存储点(例如,在对数据集进行至少五分钟和100次写入之后,您可以拥有多个存储点)。然而,您通常每五分钟或更长时间创建一个RDB快照,因此,如果Redis在没有正确关闭的情况下停止工作,您应该做好丢失最近几分钟数据的准备。
- RDB经常需要fork(),以便使用子进程在磁盘上持久化。如果数据集很大,fork()可能会很耗时,并且可能导致Redis在数据集很大且CPU性能不好的情况下停止为客户端服务几毫秒甚至一秒钟。AOF也需要fork(),但频率较低,并且您可以调整重写日志的频率,而不需要在耐久性方面进行任何权衡。
AOF
-
appendonly
-
appendfsync
always
收到命令就立即写入到磁盘中,效率最慢,但能保证完全的持久化everysec
每秒写入磁盘一次,在性能和持久化方面做了很好的折中no
完全依赖os,一般同步周期为30秒
-
优点
:
- 使用 AOF Redis 更加耐用:您可以有不同的 fsync 策略:根本不进行 fsync、每秒进行 fsync、每次查询时进行 fsync。 采用每秒fsync的默认策略,写入性能仍然很棒。 fsync 是使用后台线程执行的,当没有 fsync 正在进行时,主线程将努力执行写入,因此您只能丢失一秒钟的写入。
- AOF 日志是仅追加日志,因此不会出现查找问题,并且在断电时也不会出现损坏问题。 即使由于某种原因(磁盘已满或其他原因)日志以半写命令结束,redis-check-aof 工具也能够轻松修复它。
- 当 AOF 太大时,Redis 能够在后台自动重写 AOF。 重写是完全安全的,因为当 Redis 继续追加到旧文件时,会使用创建当前数据集所需的最少操作集生成一个全新的文件,一旦第二个文件准备就绪,Redis 就会切换这两个文件并开始追加到 新的那一个。
- AOF 以一种易于理解和解析的格式依次包含所有操作的日志。 您甚至可以轻松导出 AOF 文件。 例如,即使您不小心使用 FLUSHALL 命令刷新了所有内容,只要在此期间没有执行日志重写,您仍然可以通过停止服务器、删除最新命令并重新启动 Redis 来保存数据集 再次。
-
缺点
:
- 对于相同的数据集,AOF 文件通常比等效的 RDB 文件大。
- AOF 可能比 RDB 慢,具体取决于确切的 fsync 策略。 一般来说,将 fsync 设置为每秒一次的性能仍然非常高,并且禁用 fsync 后,即使在高负载下,它也应该与 RDB 一样快。 即使在巨大的写入负载的情况下,RDB仍然能够对最大延迟提供更多的保证。
RDB+AOF(默认)
Redis内存淘汰机制
noeviction
(默认):达到内存限制时不会保存新值。当数据库使用复制时,这适用于主数据库allkeys-lru
:保留最近使用的密钥,删除最近最少使用 (LRU) 的键allkeys-lfu
:保留常用的键,删除最不常用 (LFU) 的键volatile-lru
:删除最近最少使用的键,并将过期字段设置为 truevolatile-lfu
:删除最不常用的键,并将过期字段设置为 trueallkeys-random
:随机删除键,为新添加的数据腾出空间volatile-random
:随机删除过期字段设置为 true 的键volatile-ttl
:删除过期字段设置为 true 且剩余生存时间 (TTL) 值最短的密钥
Redis对过期Key的处理
惰性删除
:当访问key时,才判断是否过期,过期则删除(对CPU友好,但如果一个key长期不用,一直在内存中,会造成内存浪费)定时删除
:设置键的过期时间的同时,创建一个定时器,当达到过期时间点时,立即执行key的删除操作(对CPU不友好,需要让CPU维护定时器)定期删除
:隔一段时间,对数据进行一次检查,删除里面过期的key(至于删除多少过期key,检查多少数据,则由算法决定)