Redis知识点总结

Redis知识点总结

简介

Redis的16个DB

redis默认是有16个db组成,默认操作的一半都是第0个,这些DB主要有以下特点:

  1. 不支持自定义数据库名词
  2. 每个数据库不能单独设置授权
  3. 每个数据库之间并不是完全隔离的。 可以通过flushall命令清空redis实例面的所有数据库中的数据
    通过 select dbid 去选择不同的DB 。 dbid的取值范围默认是0 -15

Redis的数据结构

主要有5种

  1. 字符类型(String)
  2. 散列类型(hash)
  3. 列表类型(List)
  4. 集合类型(Set)
  5. 有序集合类型(ZSet)

Redis的应用场景

  1. 数据缓存
  2. 单点登录
  3. 秒杀类活动
  4. 网站访问排名
  5. 应用模块开发

Redis常用命令

String命令用法含义
set key valueset aaa aaa缓存一个字符串类型aaa,key是aaa,value是aaa
get keyget aaa从缓存中获取一个key是aaa的数据
incr keyincr bbb将key是bbb的数据进行递增,类似i++,value必须是数字
incrby key incrementincrby bbb 5将key是bbb的数据加5
decr keydecr bbb将key是bbb的数字递减,类似i–
decrby keydecrby bbb 3将key是bbb的数字减3
append key valueappend aaa 000将key是aaa的数据尾部添加000,比如说之前aaa的值是aaa,操作之后aaa的值是aaa000
strlen keystrlen aaa获取key是aaa的数据长度
mget key key …mget aaa bbb同时获取多个key的数据
mset key value key value …mset ccc 111 ddd 222同时设置多个key和value
Hash命令用法含义
hset map key valuehset user name zhangsan设置user对象的name字段为zhangsan,设置多个就是一个对象,hash就可以用来表示这个关系
hmset map key1 value1 key2 value2 …hmset user …一次设置多个属性,相当于上边的批量添加
hsetnx map key valuehnxset user age 13如果user对象的age属性不存在,那就设置这个属性值
hget map keyhget user name获取user对象的name属性
havls maphavls user获取整个map的值,也就是user对象
hkeys maphkeys user获取user所有的属性值
hlen maphlen user获取user的字段数量
hdel map key1 key2hdel user name age删除一个或多个哈希表字段
hexists map keyhexists user name查看user对象不否存在name字段
List命令用法含义
key valuelpush eee 111从左边往列表插入数据
rpush key valuerpush eee 222从右边往列表插入数据
lpop keylpop eee从列表左边弹出数据,会把数据从列表删除
rpop keyrpop eee从列表右边弹出数据,也会删除
llen keyllen eee获取列表的长度
lrange key start stoplrange eee 0 3从列表做边开始获取范围数据,范围就是0-3,stop为-1时表示列表最大值,也就是最右边第一个元素
lrem key count valuelrem eee 1 3从列表中删除1个值为3的数据
lset key index valuelset eee 0 5把列表中key是eee的数据下标为0的值改成5
Set命令用法含义
sadd set valuesadd mySet 1添加元素
smembers setsmembers mySet查看全部元素
sismember set valuesismember mySet 3判断是否包含某个值
srem set valuesrem mySet 1删除某个元素
srem set value1 value2srem mySet 2 4删除某些元素
scard setscard mySet查看元素个数
spop setspop mySet随机删除一个元素
smove set1 set2 valuesmove yourSet mySet 2将一个set的元素移动到另外一个set
sinter set1 set2sinter yourSet mySet求两set的交集
sunion set1 set2sunion yourSet mySet求两set的并集
sdiff set1 set2sdiff yourSet mySet求在yourSet中而不在mySet中的元素
ZSet命令用法含义
zrange zset start stopzrange zset 0 3获取排名最后三位,
start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,
以 1 表示有序集第二个成员,以此类推。
你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。
zrevrange zset start stopzrevrange zset 0 3获取排名前三(默认是升序,所以需要 rev 改为降序)
zrank zset valuezrank zset zhangsan获取zhangsan的排名
Lua脚本用法含义
evelevel(…)运行lua脚本

Redis分布式锁的实现

mysql
建个表,根据for update 或者乐观锁,或者insert和delete加唯一索引实现

zookeeper

  1. 竞争创建节点,然后监听创建成功的
  2. 根据znode,创建一个有序临时节点,

redis

#加锁,2s过期
set lock 随机数 nx px 2000
#删除锁,用lua脚本,找到 key 对应的 value,跟自己传过去的 value 做比较,如果是一样的才删除。
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

Redis数据过期策略

redis这三种都使用着,因为这三种策略是非互斥的

  1. (惰性删除)被动删除:当读/写一个已经过期的 key 时,会触发惰性删除策略,直接删除掉这个过期 key 。
  2. (定期删除)主动删除:由于惰性删除策略无法保证冷数据被及时删掉,所以 Redis 会定期主动淘汰一批已过期的 key,redis 默认是每隔 100ms 就随机抽取一些设置了过期时间的 key,检查其是否过期,如果过期就删除
  3. (缓存淘汰)主动删除:当前已用内存超过 maxmemory 限定时,触发主动缓存淘汰策略

Redis缓存淘汰策略

Redis默认只能用10G的内存

  1. volatile-lru
    当写入数据是发现内存不足,那就在设置了过期时间的key中挑选最近最少使用的key删除掉
  2. volatile-ttl
    当写入数据是发现内存不足,那就在设置了过期时间的key中把快要过期的某个key提前删除
  3. volatile-random
    当写入数据是发现内存不足,那就在设置了过期时间的key中随机删除
  4. allkeys-lru
    当写入数据时发现内存不足,那就在所有key中挑选最近最少使用的key删除掉,也是最常用的策略
  5. allkeys-random
    当写入数据时发现内存不足,那就在所有的key中随机删除某个key
  6. no-enviction
    当内存不足以容纳新写入数据时,新写入操作会报错,一般没人用吧

Lua

全局变量 local a = 1;
局部变量 a =2;

逻辑表达式
+ - * /
相等 ==
不等于 ~=
大于 >
小于 <
取余 %
负号 -
逻辑运算符
and /or /not
拼接 … eg : print(a…b)
获取长度 #
条件判断
if … then elseif … then else … end
循环
while … do … end

for i=0,10 do print(i) end

–[[范围注释]] --单行注释

函数
全局函数
local function(str…) … end

局部函数
function(str…) … end

Redis持久化策略

RDB(dump.rdb)

RDB会按照规则定制从内存把数据持久化到磁盘
快照(Snapshot)
redis在指定的情况下会触发快照
1.自己配置的快照规则
save save 秒-单位时间 在这个时间内更改次数大于某个值时会执行快照
save 10 3 就是在10秒内更改次数超过3次就会执行快照
2.通过save或者bgsave命令
save执行内存的数据同步到磁盘的操作,这个操作会阻塞客户端的请求.
bgsave在后台异步执行快照,这个不会阻塞客户端请求
3.执行flushall的时候
清除内存的所有数据,只要配置的规则存在,那就会执行快照
4.执行复制的时候

快照实现原理
redis会使用fork函数复制一份当前进程的副本(子进程),fork进程负责把内存的数据同步到磁盘的临时文件,父进程继续处理客户端请求
优点:
可以最大化redis的性能,但是数据量很大的话,fork时间过久也会影响一些性能
缺点:
可能会存在数据丢失的请求,也就是快照和下一次快照的中间,redis挂了

AOF

AOF是每次执行命令后,把命令本身记录到磁盘
开始AOF的方式就是在配置文件中把appendonly设置成yes,默认的文件名就是appendonly.aof
每次命令都保存,那些旧数据也被保存了,徒增烦恼,我们只需要最新的数据而已,redis配置文件中有压缩策略解决了这个
如下两个参数可以去对aof文件做优化
auto-aof-rewrite-percentage 100 表示当前aof文件大小超过上一次aof文件大小的百分之多少的时候会进行重写。如果之前没有重写过,以启动时aof文件大小为准
auto-aof-rewrite-min-size 64mb 限制允许重写最小aof文件大小,也就是文件大小小于64mb的时候,不需要进行优化

aof重写的原理
Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松
同步磁盘数据时的问题
redis每次更改数据的时候, aof机制都会将命令记录到aof文件中,但是由于操作系统的缓存机制,数据并没有实时的写入到硬盘中,而是先写入到了硬盘缓存。再通过硬盘缓存机制去保存到文件中,所以在这个时间段之内如果redis挂了,那就会存在数据同步问题,redis提供了appendfsync参数来解决这个问题.

  1. appendfsync always 每次执行写入都会进行同步,这个是最安全但是是效率比较低的方式
  2. appendfsync everysec 每一秒执行一次同步,就算丢失也是1秒的数据,是可接受的
  3. appendfsync no 不主动进行同步操作,交给操作系统去执行同步操作这个是速度最快的,但也是最不安全的方式

写入AOF的时候系统宕机怎么办
在写入AOF和同步到磁盘的时候,系统宕机了,结果造成了AOF文件损坏,那在redis重启的时候是不会加载损坏的AOF文件的,这样就造成了数据的不一致或者丢失的情况,redis本身提供了AOF文件修复工具,具体操作如下:
1.先备份一下AOF文件
2.使用Redis提供的 redis-check-aof 程序来修复原来的AOF文件,执行redis-check-aof --fix命令即可,修复完成后重启,RDB也有一个修复工具,道理相同

缺点
响应请求的同时还要写磁盘,稍微会影响性能,但是还是IO得问题,换固态即可

缓存击穿

key不存在

缓存穿透

key过期

缓存雪崩

宕机

总结

可单独使用也可一起使用,如果一起使用,当redis启动或重启时,redis会优先使用AOF来还原数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值