redis一本通

docker 一条龙 #

docker run -p 6379:6379 -d redis:latest
redis-server #跑

docker exec -it xxx redis-cli -h 0.0.0.0 -p 6379 # id要换成自己的
> ping #Pong 测试
> set name xinbao # 设置 获取值
> get name
> info # 查看信息

推荐这个可视化工具: AnotherRedisDesktopManager

以下正文。

优势特点 #

redis 数据结构数量从过去 5 种,增加到了 9 种。

Redis 特点思维导图

并发操作,很有可能 mysql 一千并发就扛不住了,造成数据库雪崩。

优势:

  • 性能好。读 11w/s,写 8.1w/s
  • 数据类型丰富。
  • 单个原子性,要么成功要么失败完全不执行
  • 多个操作支持事务
  • 丰富的特性,支持发布订阅,通知,key 过期等。

api #

介绍 api 使用

【redis api 思维导图】

进入 #

redis-server
redis-server /myRedis.conf # 载入conf
# 设置

字符串 #

set key value # 设置 k-v
set key value nx # redis2.6+ 没有值才操作
set key value xx # redis2.6+ 有值才操作

# 获取
get key # 没有值就是 nil

# append 追加
append key newValue

# 获取旧值并赋新值
getset key newValue

# 获取一部分字符串,字符串范围
getrange key start end # name = afpx
getrange name 1 2 # 返回 fp


# 数字原子操作
set age 1
incr age # +=1
incrby age 5 # +=5

decr age # -=1
decrby age 2 # -=2

# exists 是否存在
exists age # 是否存在 0false不存在 1存在

# 删除
del age

# expire 过期时间
expire age 10 # 10s后过期
ttl age # time to live 剩余存活时间 返回 10, 返回-2表示过期

# 获取值类型
type key # string

场景:

  • 缓存。字符串数据结果,也可以把热门图片缓存。
  • 计数器。记录 pv,投票记录
  • 限速器。ip 一分钟 60 个请求。错误密码多了不让登陆。

哈希 #

哈希,也叫散列,hash,就是 key-value 的映射表。

hset # hash set
hest user name xinbao # key name value
hset user age 9

hget user name # 获取
hgetall user # 所有 key 的结果

hmset user k1 v1 k2 v2 # mult 设置多个值

hdel user name # 删除属性
hkeys user # 获取key

场景:

  • 短网址生成工具。

链表 #

列表,链表。 读取很慢,插入新元素很快。

lpush ids 2
lpush ids 1 # 左边插入元素和值

rpush ids 3 # 右边插入

lrange ids 0 -1 # 全部列表,索引-1 最后一个

lpop ids # 左端弹出
rpop ids # 右端弹出

lindex ids 1 # 查看索引1
llen ids # 查看长度

lrem key 0 2 # 第一个值是num,0表示所有 # 删除值等于2 # 删除所有2
lrem key 2 1 # 删 两个 1
lrem key -1 1 # 倒着删

集合 #

字符串类型的无序集合。

没有重复的。

sadd # set add
sadd tags 1
sadd tags 2 3 4
smembers tags # 查看所有成员
scard tags # 集合长度
srem tags 4 # 删除了
# 标签云
sadd a 1 2 3
sadd b 2 3 4
sinter a b # 2 3 两个集合的交集
sdiff a b # a-b 的东西
sunion a b # a b 的并集

有序集合 #

z 开头。每个集合会关联一个 double 的分数,通过分数来分类排序。

zadd key score1 memeber1 [score2 member2]
zadd stus 60 zhangsan 70 lisi 80 wangwu # 60-80分的学生
zcard stus # 返回3
zadd level 1 one
zrange stus 0 -1 # 返回成员
# 插入新成员会自动排顺序
zrange stus 0 -1 withscores # 显示成员和积分
zrem stus memeber # 删除一个成员

以上是 api 的大部分内容。

node 里使用 redis #

  • redis
const redis = require('redis')
const client = redis.createClient()
client.on('error',()=>{})
client.set('home','beijing',client.print)

redis 发布订阅 #

通知其他部门。

subscribe channel1 # 订阅频道

publish channel1 hello # 向频道里发送消息

node 实现

const redis = require("redis");
const client1 = redis.createClient();
const client2 = redis.createClient();
client1.subscribe("aaa");
client1.subscribe("bbb");

client1.on("message", (channel, msg) => {
  console.log();
  client1.unsubscribe("");
});
client2.publish("aaa", "msg1");
client2.publsi;

事务 #

不是一个事务的概念,没有回滚,只是个语法糖,走事务还是得 mysql 这样的。

redis 命令是原子性的,redis 里的事务可以理解为批量执行的脚本。中间失败不会影响之前的回滚,也不会影响后续的执行。

multi # queued
set k1 v1 # 进入队列
set k2 v2
exec # 执行

node 写法

const redis
client = redis.createClient()
client.multi().set().set().exec((err,res)=>{})

持久化 #

rdb #

dump.rdb 文件,关机时候会写入。

save() # 保存版本

生成的文件可以随便放,随时覆盖恢复。

Rdb 一旦非法关闭,会丢失最后一次持久化之后的数据。如果数据不重要,不必担心,如果不能丢失,要使用 aof 方式。

aof #

默认不使用。操作一次 redis 数据库,就把操作记录存储到持久化文件中。

开启。修改为redis.conf

appendonly yes
appendfilename "appendonly.aof"

如果 redis 重启,数据从 aof 文件加载。

用什么策略需要权衡。

高可用 #

硬盘花了,意外断电。

主从,多从,哨兵系统。 哨兵发现主机有故障,自动把从机变成主机,主机恢复了再上线变成主机。

数据淘汰策略 #

Redis 过期删除采用的是定期删除,默认是每 100ms 检测一次,遇到过期的 Key 则进行删除,这里的检测并不是顺序检测,而是随机检测。 那这样会不会有漏网之鱼?显然 Redis 也考虑到了这一点,当我们去读/写一个已经过期的 Key 时,会触发 Redis 的惰性删除策略,直接回干掉过期的 Key。

集群 #

关键词: codis redis cluster3.0

一致性 #

真正意义上来讲数据库的数据和缓存的数据是不可能一致的,数据分为最终一致和强一致两类。如果业务中对数据的要求必须强一致那么就不能使用缓存。缓存能做的只能保证数据的最终一致性。

缓存击穿 #

缓存击穿。如果被黑客利用,频繁去访问缓存中没有的数据,瞬间所有请求的压力都落在了数据库上,导致数据库连接异常。 解决方案: 1、后台设置定时任务,主动地去更新缓存数据。这种方案容易理解,但是当 Key 比较分散的时候,操作起来还是比较复杂的。 2、分级缓存。比如设置两层缓存保护层,1 级缓存失效时间短,2 级缓存失效时间长。有请求过来优先从 1 级缓存中去查找,如果在 1 级缓存中没有找到相应数据,则对该线程进行加锁,这个线程再从数据库中取到数据,更新至 1 级和 2 级缓存。其他线程则直接从 2 级线程中获取。 3、提供一个拦截机制,内部维护一系列合法的 Key 值。当请求的 Key 不合法时,直接返回。

缓存雪崩 #

缓存雪崩就是指缓存由于某些原因(比如宕机、Cache 服务挂了或者不响应)整体 Crash 掉了,导致大量请求到达后端数据库,从而导致数据库崩溃,整个系统崩溃、发生灾难,也就是上面提到的缓存击穿。 如何避免雪崩: 1、给缓存加上一定区间内的随机生效时间,不同的 Key 设置不同的失效时间,避免同一时间集体失效。 2、和缓存击穿解决方案类似,做二级缓存,原始缓存失效时从拷贝缓存中读取数据。 3、利用加锁或者队列方式避免过多请求同时对服务器进行读写操作。

写给 redis 零基础同学的上手攻略 https://juejin.im/post/5b90001ce51d450e452a620d


推荐的扩展阅读

  • npm 包 ioredis
  • redis4.x cookbook

其他链接

https://zhuanlan.zhihu.com/p/42272979

https://juejin.im/post/5b516dc75188251af363492d

https://juejin.im/post/5a912b3f5188257a5c608729

https://juejin.im/post/58330053570c350059e0bb08

https://blog.csdn.net/qq_33589252/article/details/85535890

https://blog.csdn.net/carlosfu/article/details/84765191

https://juejin.im/post/5b90001ce51d450e452a620d

https://juejin.im/book/5afc2e5f6fb9a07a9b362527/section/5b336601f265da598e13f917