Redis基础整合
Redis基础操作、事务、乐观锁、持久化、主从复制、哨兵、缓存穿透击穿雪崩
查看所有key、删除指定的key和清除所有key
keys * //查看当前表的所有key
del key1 //删除指定key1
flushall //清除全部
flushadb //清除当前表
String
set key1 v1 //创建键值对
mset k1 v1 k2 v2 k3 v3 //批量创建k1 k2 k3
setex k3 30 hello //创建k3,值为”hello“,30s后过期
setnx k1 hello //如果key1不存在则创建key1,若存在则创建失败
msetnx //批量创建(是一个原子性的操作,要不都成功,要不都失败)
get key1 //查看键值对
mget k1 k2 k3 //批量查看k1 k2 k3
append key1 “hello” //追加值
incr views //值加一
decr views //值减一
incrby views x //值加x
decrby views x //值减x
getrange key1 x y //截取字符串 从x到y
setrange key2 x x` //替换指定位置的字符串 把x位置的字符串替换为x`
set user:1 {name:zhangsan,age:23} //用json字符串创建一个对象
mset user:2:name lisi user:2:age 19 //巧妙设计key创建对象
getset k4 redis //组合命令,先get再set,先返回get命令再set创建
List
'所有的list命令都是以 L/l(redis命令不区分大小写) 开头的'
LPUSH list A //从链表左边插入
RPUSH list B //从链表右边插入
Lrange list x y //查看所有位置从x到y的链表元素
Lrange list 0 -1 //查看所有链表元素
LPOP list //移除链表左边第一个元素
RPOP list //移除链表右边第一个元素
Lindex list x //获得链表第x个元素
Llen list //获得链表的长度
Lrem list 1 one //移除链表中一个指定的值
Ltrim list x y //截取从 x 到 y 指定长度的元素,其他的元素删除
RPOPLPUSH list newlist //组合命令,取出 list链表 的最右边元素,插 入 newlist链表 的最左边
lset list x item //把 list链表 中的第x个元素替换为item(更新操作,值不存在则报错)
linsert list before( after ) "B" "X" //在链表的”B“元素之前( 后 )插入 ”X“元素
Set
'set是无序不重复集合'
sadd set ”A“ //创建 set,添加元素
smembers set //查看 set 中所有元素
sismember “A” //判断是否存在"A"这个元素
scard set //获取 set 集合中的元素的个数
srem set "A" //移除set集合中的元素"A"
srandmember set x //随机从 set 集合中抽选出 x 个元素
spop set x //随机移除 set 集合中 x 个元素
smove set1 set2 "A" //把 "A" 元素从 set1 集合中移到 set2 集合
sdiff set1 set2 //获得 set1 集合和 set2 集合不相同的元素
sinter set1 set2 //获得 set1 集合和 set2 集合的相同元素( 交集 )
Hash
'Map集合:key-map(key - (key-value) ) , 这时候值是一个map集合'
hset hash field1 A //创建一个 hash ,并添加元素
hmset hash field1 "ABC" field2 "abc" //批量创建hash表,并添加元素
hget hash field1 //获取hash表中的元素
hmget hash field1 field2 //批量获取hash表的元素
hgetall hash //获取所有元素
hdel hash field2 //删除hash表中的元素
hlen hash //查看hash表的长度
hexists hash field1 //判断hash中的指定key是否存在
hkeys hash //获取hash中的所有的key
hvals hash //获取hash中的所有的value
hincrby hash field1 1 //hash中 value 自增1
hdecrby hash field1 1 //hash中 value 自减1
hsetnx //用法和set集合相同
Zset
'有序集合,在set基础上,增加了一个值,set k1 v1 <——> zset k1 score1 v1'
zadd set 1 A //添加一个值"A"
zrange set 0 -1 //查看元素
zrangebyscore set -inf +inf //从负无穷到正无穷排序
zrangebyscore set -inf +inf withscores //从负无穷到正无穷排序,并显示score
zrangebyscore set x y withscores //从 x 到 y 排序,并显示score
zrevrange set 0 -1 //从大到小排序
zrem set A //移除 set 中的元素"A"
zcard set //获取 set 集合中的个数
zcount set x y //获取 set 集合中 x 到 y 元素的数量
Geospatial
'地理位置,定位,附近的人,打车距离计算( 本质用Zset实现的 )
有效经度-180 ~ +180 ,有效纬度 -85 ~ +85'
geoadd china:city 116.40 39.90 beijin //添加key - 经纬度 城市
geopos china:city beijin //获取指定位置的经纬度
geodist china:city beijin shanghai (m/ km/ mi英里/ ft英尺) //获取两个位置之间的距离
georadius china:city 110 30 10000 km(withdist直线距离 /withcoord经纬度) (count x 限定获得 x 个位置 ) //搜索经度为110 纬度为30 周围10000km的位置 (附近的人)
georadiusbymembers china:city beijin 10000 km //搜索 beijin 位置 周围10000km的位置
zrange china:city 0 -1 //查看所有key中所有value
zrem china:city beijin //删除beijin
.
Hyperloglog
'基数统计的算法(网页的访问量,一个人访问多次还是算一个人,可接受误差)'
'传统方式:set集合保存用户id,统计set中id数量(不利于用户过多)'
'Hyperloglog优点:占用内存很小,是固定的。'
PFADD key1 a b c d d //把元素存入key1
PFCOUNT key1 统计 key1 //元素基数的个数
PFMERGE key3 key1 key2 //合并key1 和 key2 两组到key3(并集)
Bitmaps
'位图,是操作二进制数来进行记录,位存储 1 0(登录/未登录 打卡/未打卡)'
setbit sign x 0/1 //在第 x 个位置存入0或者1
getbit sign x //查看第 x 个位置为 0还是1
bitcount sign x y //统计从 x 到 y 有多少个1
事务
Redis事务: 一次性、顺序性、排他性。
Redis事务本质:一组命令的集合,一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行。
Redis事务没有隔离级别的概念(所有的命令在事务中,并没有直接执行,只有发起执行命令的时候才会执行)
Redis单条命令是原子性的,但事务不保持原子性!!!
redis事务:1、开启事务( multi ) 2、命令入队( ...... ) 3、执行事务( exec ) 放弃事务( discard )
编译型错误(代码有问题,命令有错),事务中所有的命令都不会被执行! 运行时错误(比如 1/0 ),错误命令会抛出,但不影响其他命令执行!
乐观锁
悲观锁:很悲观,认为什么时候都会出现问题,无论做什么都会加锁
乐观锁:很乐观,认为什么时候都不会出问题,所有不会加锁。 在更新数据的时候去判断一下,再此期间是否有人修改这个数据。
监视一个key(加乐观锁)(加乐观锁后,如果执行之前,其他线程修改这个 key 时,就会导致事务执行失败)
watch key1 //监视key1,给key1上锁
unwatch key1 //取消监视key1,给key1取锁
持久化
RDB (redis database)(把数据保存在一个 .rdb 文件中)
AOF (append only mode)(把操作保存在一个 .aof 文件中,默认的文件的无限追加)
主从复制
主机能读写,从机不能写,只能读。
从机宕机后,重新连接到主机能重新复制主机的全部数据
哨兵模式
'配置文件sentienl.conf':
sentinel monitor myredis( 被监控的名称 ) 127.0.0.1( host ) 6379( port ) 1( 1代表主机挂了,哨兵对slave进行投票,谁票数多,谁就成为新的主机 )
启动哨兵:sentinel-server sentient.conf
如果Master节点断开了,这个时候就会从slave中随机选择一个服务器!(这里面有一个投票算法 !)
如果断开的Master重新连接,不能重新成为主机,只能变成新的主机下的从机!
优点:主从可以自动切换,系统可用性更好。
缺点:Redis不好在线扩容,集群容量一旦达到上限,在线扩容就十分麻烦。
缓存穿透、击穿、雪崩
缓存穿透(缓存和mysql数据库都查不到)
解决:1、在缓存前面加一个布隆过滤器 2、在缓存中存储一个空值,返回给请求
缓存击穿(请求的量太大,缓存过期击穿缓存,比如微博热搜)
解决:1、热点数据永不过期 2、加互斥锁( 保证只有一个线程获得key,其他线程等待)
缓存雪崩(缓存集中过期失效,缓存层发生生效):
解决:1、异地多活 2、限流降级 3、数据预热