知识整理 Redis

Redis官网

本文档持续更新中...

0)redis相关面试题
  • 与Memcached区别
支持多数据类型
支持持久化
单线程+IO多路复用

串行 vs 多线程+锁(Memcached) vs 单线程+IO多路复用(redis)

  • AOF和RDB同时开启,Redis听谁的?
系统默认取AOF的数据,数据不会存在丢失
  • AOF和RDB用哪个好?
官方推荐两个都用;
对数据不敏感,单独使用RDB;
不建议单独使用AOF;
如果只是做纯粹的内存缓存,可以都不用。

1)redis-cli使用命令
redis-cli [options] [commands]
# 常见的options有:
-h 127.0.0.1
-p 6379      # Merz
-a pwd_123   # 登录密码
# 也可以后输入密码
auth pwd_123
# commands
ping         # 返回pong

2)redis命令

redis数据结构,key一般是string类型,value有8种
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/8109138c55f3461c9f7ee52ccf36f3fb.png

具体命令建议通过官方文档查看,边查边记录,活学活用
在这里插入图片描述

  • 通用命令
select 14      # 切换数据库
dbsize         # 查看当前库的key数量
flushdb		   # 清空当前库
flushall       # 通杀全部库

# 查询某个命令如何使用? help xxx
keys a*    # 查询以a开头的key  
type key
del k1 k2 k3
unlink k2  # 异步删除
mset k1 v1 k2 v2 k3 v3
exists k1
expire k1 60*5
ttl k1     # -1,-2
...
  • String类型命令
set k1 v1
get k1
append k1 abcdefg
strlen k2
mset k1 v1 k2 v2 k3 v3
mget k1 k2 k3
incr k1     # 原子性操作,不会被线程调度机制打断的操作
incrby k1 3
incrby k1 -3
incrbyfloat k2 0.5
setnx k5 v5
setex k6 60 v6
msetnx k1 v1 k2 v2 k3 v3  # 有一个失败则全部失败
getrange k1 0 3
setrange k1 0 abc
getset k1 v3
...
# key可以设置为层级结构:
set project:user:1 '{"id":1, "name":"jack"}'
set project:user:2 '{"id":2, "name":"lucy"}'

set project:product:1 '{"id":1, "name":"小米"}'
set project:product:2 '{"id":2, "name":"华为"}'
...

String类型的数据结构为简单动态字符串,是可以修改的字符串,内部结构实现类似于Java的Array List,采用预分配冗余空间的方式来减少内存的频繁分配

  • Hash类型命令
hset k1 field1 v001
hget k1 field1
hmset k2 field2 v002 field3 v003
hget k2 field2 field3
hgetall k2
hkeys k2
hvals k2
hincrby k2 field2 23
hsetnx k2 field2 v003
...

hash类型对应的数据结构是两种:ziplist,hashtable

  • List类型命令
lpush k1 v1 v2 v3
lrange k1 0 -1     # v3, v2, v1
rpush k1 v1 v2 v3
lrange k1 0 -1     # v1, v2, v3
lpop/rpop v1       # 键在值在,值光键亡
rpoplpush k1 k3
lindex k2 4
llen k2
linsert k2 before/after "v1" "v11"
lrem k2 2 "v2"
lset k2 1 "v111"
...

单键多值,底层是一个双向列表,对两端的操作性能很高,但是通过索引下标操作中间节点性能较差。 快速链表:quickList

  • Set类型命令
sadd k1 v1 k2 v2
smembers k1
sismember k1 v1
scard k1
srem k1 v1 v2
spop k1
srandmember k2 2
smove k1 k2 v3
sinter k1 k2
sunion k1 k2
sdiff k1 k2
...

Redis的Set是String类型的无序集合,底层是一个value为null的hash表,添加、删除、查找的复杂度都是O(1),数据结构是Dict

  • Zset类型命令(有序集合)
zadd topn 200 java 300 c++ 400 python
zrange topn 0 -1  [withscores]
zrangebyscore topn 300 400 withscores
zrevrangebyscore topn 300 400 withscores
zincrby topn 40 java
zrem topn java
zcount topn 200 300
zrank topn java
...

3)配置文件详解
vim redis.conf
  • units: 配置大小单位,只支持bytes,不支持bit,大小写不敏感
    在这里插入图片描述
  • INCLUDES
  • NETWORK
bind 127.0.0.1 -::1
protected-mod yes # 只能本机访问
port 6379
tcp-backlog 511   # 是一个连接队列,未完成三次握手队列+已完成三次握手队列,高并发环境下可以调大该值
timeout 0         # 永不超时
tck-keepalive 300 # 检查心跳时间
  • GENERAL
daemonize yes
pidfile /var/run/redis_6379.pid  # 进程号
loglevel notice
logfile ""
databases 16
  • SECURITY
requirepass pwd_123 # 也可以通过命令:config set requirepass "123456"
  • LIMITS
maxclients 10000
maxmemory
mexmemory-policy
mexmemory-samples
  • SNAPSHOTTING
# RDB
dbfilename dump.rdb
dir ./
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes   # 大约有10%的性能损耗
save
bgsave

# AOF
appendonly yes
appendfilename "appendonly.aof"
appendfsync always/everysec/no

# 主从复制
replica-priority 100  # 值越小优先级越高

4)发布订阅

一种消息通信模式,举例命令行实现,分别打开两个客户端

# 第一个客户端订阅频道
subscribe channel001
# 第二个客户端发送消息
publish channel001 hello  # 返回的是订阅者数量

5)新数据类型 # todo
  • Bitmaps
  • HyperLogLog
  • Geospatial

6)事务和锁机制
  • 事务定义
    Redis事务是一个单独的隔离操作,事务中所有的命令都会序列化、按顺序的执行。事务在执行过程中,不会被其他客户端发来的命令请求所打断。Redis事务的主要作用就是串联多个命令防止别的命令插队。
  • 基本操作:Multi,Exec,Discard
    multi阶段某个命令出现错误,exec时所有队列都会取消,
    multi阶段没有错误,exec时某个命令出现错误,只有这个不会被执行。
  • 事务冲突
    在这里插入图片描述

悲观锁:拿到数据时先上锁,这样别人想拿到这个数据时,就会一直block直到拿到锁。
缺点:效率低

在这里插入图片描述

乐观锁:每次拿到数据的时候不会上锁,在更新的时候会判断在此期间有没有人修改数据,可以使用版本号机制。乐观锁适用于多读的应用类型,可以提高吞吐量,Redis就是利用这种check-and-set机制实现事务的。(抢票就是典型的乐观锁设计)

在这里插入图片描述

watch key [key…] :如果在事务执行之前,key被其他命令所改动,那么本次事务被打断
unwatch: 取消监视

  • Redis事务三个特性
    - 单独的隔离操作:事务中所有的命令都会序列化、按顺序的执行。事务在执行过程中,不会被其他客户端发来的命令请求所打断;
    - 没有隔离级别的概念:队列中的命令没有提交之前都不会被实际执行,因为事务提交前任何指令都不会被实际执行;
    - 不保证原子性:事务中如果有一条执行失败,其他命令照常执行,没有回滚。

7)持久化
  • RDB,在指定时间间隔内,将内存的数据集快照写到磁盘

Redis会单独创建一个子进程来进行持久化,会先将数据写到一个临时文件,待持久化过程结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据恢复,且对于数据恢复的完整性不是特别敏感,那么RDB比AOF更加高效。
RDB的缺点是:最后一次持久化的数据可能丢失。
写时复制技术

在这里插入图片描述

优势:
适合大规模的数据恢复;
适合对数据完整性和一致性要求不高场景;
节省磁盘空间;
恢复速度快。

劣势:
fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑;
虽然fork时使用了写时复制技术,但是如果数据庞大会比较消耗性能;
最后一次数据可能丢失。
  • AOF,以日志的形式来记录每个写操作(增量保存),只许追加文件不可以修改文件 ,默认不开启

持久化流程:
客户端的请求写命令会被append到AOF缓冲区内;
AOF缓冲区根据AOF持久化策略将操作sync同步到磁盘的AOF文件中;
AOF文件大小超过重写策略或者手动重写时,会对AOF文件进行Rewrite重新,压缩AOF文件容量;
Redis重启服务时,会重新load AOF文件中的写操作达到数据恢复的目的。

AOF文件损坏:
/usr/local/bin/redis-check-aof--fix appendonly.aof # 然后重启

Rewrite:todo

优势:
备份机制更稳健,丢失数据概率更低;
可读的日志文件,可以处理误操作。

劣势:
比RDB占用更多的磁盘空间;
备份恢复速度慢;
每次写都同步的话,有一定性能压力;
存在个别bug,导致恢复失败

8)主从复制

主机数据更新后根据配置的策略,自动同步到备机,master写slave读。读写分离,容灾快速恢复。

一主两从搭建(关闭AOF)

# 1,创建/myredis文件夹
# 2,复制redis.conf文件到myredis
# 3,配置一主两从,创建三个配置文件:
redis6379.conf
redis6380.conf
redis6381.conf
# 4,在6379配置文件中写入内容,同样配置6380和6381
include /myredis/redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb	
# 5,根据三个配置文件启动三个进程,连接后
info replication # 查看主从信息
# 6,配从不配主,在6380和6381执行
slaveof 127.0.0.1 6379
# 7,测试,在master写数据,在slave查看(slave无法写操作)

在这里插入图片描述

常用三招

  • 一主二仆
一个slave挂掉并重启后,需要重新执行slaveof,挂掉期间产生的数据会自动同步到slave中;
master挂掉后,两台slave原地待命,master重启后恢复原样
  • 薪火相传
master > slave1 > slave2(再执行slaveof slave1),缺点:slave1挂掉?
  • 反客为主
slaveof no one  # slave变master,缺点:手动处理

复制原理:
1,当slave连接上master以后,slave向master发送进行数据同步消息
2,master收到消息后,把数据持久化到RDB文件,然后把文件发送给slave,slave拿到文件后进行读取;(全量复制)
3,每次master写操作之后,会主动进行数据同步;(增量复制)

哨兵模式(反客为主的自动版)

# 自定义的/myredis目录下新建sentinel.conf文件
# 配置哨兵文件
sentinel monitor mymaster 127.0.0.1 6379 1 # 至少有多少个哨兵同意迁移的数量
# 启动哨兵
redis-sentinel /myredis/sentinel.conf

在这里插入图片描述


9)集群

解决的问题:

容量不够
并发写操作分摊压力
主从模式、薪火相传主机宕机导致的ip地址变化,需要重新配置相关信息

代理主机
在这里插入图片描述

无中心化集群配置
在这里插入图片描述


10)应用问题解决
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值