# Redis
一、Redis 环境配置
-
下载
-
Windows:去github上下载即用
-
官网下载解压,打开终端进入redis文件夹,输入
sudo make test
测试,再输入sudo make install
编译
-
-
环境配置
-
开启redis
- windows:
- redis-server.exe:redis的服务器端
- redis-cli.exe:redis的客户端
- Mac
- 打开终端,输入
redis-server
- 重新打开一个终端,输入
redis-cli
- 打开终端,输入
- windows:
-
基础知识
- redis默认有16个数据库(0~15),默认使用第0个数据库
- redis 的默认端口号是 6379
二、五大基本类型
Redis存储数据结构有五大基本类型,在redis中无论什么数据类型都是以key-value形式保存,其中key都是字符串,value有5种不同的数据结构,通过进行对Redis-key的操作,来完成对数据库中数据的操作。
2.1 String
字符串类型:重复存储会将原来的值覆盖
set key value
:单条存储mset key1 value1 key2 value2 key3 value3
:批量存储
get key
:单条获取mget key1 key2 key3
:批量获取
del key
:删除
如果存入的 value 类型是数字,那么就可以使用计数器功能
incr key
:将 key 中储存的数字值增一decr key
: 将 key 中储存的数字值减一
2.2 list
列表类型:允许重复元素
-
rpush key value1 value2 value3
:向集合的尾部(右边)添加元素 -
lpush key value1 value2 value3
: 向集合的首部(左边)添加元素 -
lpop key
:删除列表最左边的元素,并将元素返回 -
rpop key
:删除列表最右边的元素,并将元素返回 -
lrange key start end
: 查看 start-end 元素,下标值从0开始算 -
lrange key 0 -1
:查看所有 -
llen myList
:查看列表的长度
2.3 set
集合类型 :不允许存储重复元素,集合中的元素没有先后顺序
sadd key value1 value2 value3
:存储smembers key
:检查某个元素是否存在set 中,只能接收单个元素sismember key value1
:查看key 中是否srem key value
:删除set集合中的某个元素scard kay
:查看set的大小
-
sinterstore key3 key1 key2
# 获取 key1 和 key2 的交集并存放在 key2 中假设 key1中有 1 2 3 4 、key2中有 3 4 5 6,将他们的交集存放到key3中,那么key3 中就有了3和4
2.4 hash
哈希类型:类似于 java 的 map
-
hset key field value field2 value2
:存储 -
hget key field
:获取单个field的值hgetall key
:获取所有field的值
-
hdel key field
:删除 -
hkeys key
:获取该 hash 所有的 field 名字 -
hvals key
:获取该 hash 所有的 value 名字
2.5 sortedset
有序集合类型 :不允许重复元素,且元素通过权重排序顺序
zadd key score1 value score2 value2
:一次添加多个元素zrange key start end
:从小到大排序,查看 start-end 范围内的权重值zrevrange key start end
:从大到小排序,查看 start-end 范围内的权重值zrange key 0 -1
:查看所有zrem key value
:删除sortedset 集合中的某一个元素zcard key
:查看sortedset的个数zscore key value1
: 查看某个 value 的权重
2.5 通用命令
exists key
:判断键是否存在del key
:删除键值对move key db
:将键值对移动到指定数据库expire key second
:设置键值对的过期时间type key
:查看value的数据类型
三、Redis 配置文件
-
Redis.config 配置文件对大小写不敏感
-
网络的配置
bind 127.0.0.1 -::1 #绑定哪些客户端可以访问 redis-service 可以写通配符 /* port 6379 #端口号 maxclients 10000 #设置客服端最大连接数 maxmemory-policy noevtction #内存到达上限之后的策略,有6种策略。
-
通用配置
requirepass foobared #设置 redis 密码,redis 默认是没有密码的 daemonize no #以守护进程,在后台默认运行 # debug (a lot of information, useful for development/testing) # verbose (many rarely useful info, but not a mess like the debug level) # notice (moderately verbose, what you want in production probably) # warning (only very important / critical messages are logged) loglevel notice #设置日志级别 logfile "" #文件日志输出位置 databases 16 #设置数据库大小 always-show-logo no # 是否显示logo
-
快照设置
# 如果900s,有至少1个key进行了修改,就会进行持久化操作 save 900 1 save 300 100 save 60 10000 stop-writes-on-bgsave-error yes # 持久化如果出错了,是否要继续工作 rdbcompression yes #是否压缩rdb 快照文件 rdbchecksum yes #保存rdb文件的时候,进行错误检查校验 dir ./ #rdb保存的文件位置 dbfilename dump.rdb #生成快照的文件名
四、持久化
redis持久化概念
redis是一款内存数据库,当redis服务器重启或者电脑重启数据就会丢失!我们可以将redis内存中的数据持久化保存在硬盘的文件中
3.1 redis持久化机制
3.2.1 RDB【推荐】
不需要进行配置,默认就使用这种机制
- 触发机制
- 满足配置文件中save的条件
- 执行flushall命令
- 退出redis
如何恢复rdb文件?
只需要将rdb文件放在redis启动目录即可,redis就会自动恢复
redis启动目录在哪?
config get dir
3.2.2 AOF
配置:编辑配置文件和触发机制
appendonly no-->appendonly yes
#appendfsync always:每一次操作都会进行持久化
#appendfsync everysec:每隔一秒进行一次持久化
#appendfsync no:不进行持久化
五、主从复制
什么是主从复制?
主从复制是指在redis集群中,将一个redis服务器数据复制到其他redis服务器,前者称之为主节点(master),后者为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。主节点以写为主,从节点为读为主。一个主节点可以有多个从节点,但一个从节点只能有一个主节点!
默认情况下,启动的每一个redis服务都是主节点。主从复制需要配置,一般情况下只需要配置从机即可
info replication
:查看 redis 服务的信息
配置主从复制
-
slave 主机端口号
:命令行配置主从复制,临时的! -
配置文件中配置
replicaof <masterip> <masterport>
数据同步
当一个新从机连接到主机时,master会将自己的数据全量复制给从机实现数据同步。如果主机断开了从机不会受到影响,依旧可以读取内存中的数据。
六、哨兵模式
配置哨兵
-
编写哨兵配置文件
vim sentinel.conf # sentinel.conf 内容 sentinel moitor myreids 127.0.0.1 6379 1
-
启动哨兵:
redis-sentinel ./sentinel.conf
七、缓存穿透、击穿、雪崩
7.1 穿透
穿透产生的原因
用户查询一个数据,发现redis中没有,也就是缓存没有命中。于是就向mysql查询,发现也没有,于是查询失败。当很多用户都去查询这个没有的数据,缓存都没有命中就都会去查询mysql,这样mysql压力就会很大,造成缓存穿透。
解决方案
- 布隆过滤器
- 缓存空对象
7.2 击穿
击穿产生的原因
当存储在redis的热点数据过期时,同时又有大量的请求到服务器,就容易产生缓存击穿。
例如:一个热点数据在redis中存储了60s,当到了60秒的时候这个数据就过期了,这时候又大量的请求同时到服务器了,redis还没有重新存储新的缓存!可能在这0.1秒之间,大量的请求就会到达mysql数据库,造成缓存击穿
解决方案
- 设置热点永不过期
- 使用分布式锁;当热点过期了,只允许一个请求到msyql将查询到结果存放到redis中,其他请求暂时等待。
7.3 雪崩
雪崩产生的原因
某一个redis服务节点宕机了,压力到了其他服务上另外的服务也承受不住压力从而导致一台台服务雪崩
解决方案
- 异地多活:多设置几台服务器
- 限流降级
- 数据预热:先尽可能将数据都访问一遍,预想将热点数据存储到redis中。设置不同的过期时间,让失效时间均匀点
八、事务!
8.1 开启redis的事务
- 开启事务(multi)
- 命令队列(…)
- 执行事务(exec)
multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> get k3
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) OK
4) "v3"
127.0.0.1:6379>
8.2 放弃事务
- 开启事务(multi)
- 命令队列(…)
- 执行事务(discard)
8.3 redis事务异常
8.3.1 编译型异常
语法错误报错,事务中的所有语法都将不执行
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> getset k2
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379>
8.3.2 运行时异常
该错误命令不执行,其他命令继续执行
127.0.0.1:6379> set k1 "v1"
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr k1 #此处语法报错 incr不能用在字符串上
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec
1) (error) ERR value is not an integer or out of range #执行事务后该命令报错,其他命令不影响
2) OK
3) "v2"
127.0.0.1:6379>
8.4 redis 乐观锁
举例子: redis 中有一个 save 数据为100 和 spend 数据为0 ;当我们花10元的时候 spend 数据+10,save 数据 -10。在实现这个业务的时候就需要加上事务了。假如我们在执行这个事务的时候,同时有另外一个 redis 线程改变了 save 数据值了怎么办?这时候就需要就需要用redis的乐观锁 watch 命令!
watch key
:监测一个key的值
unwatch
:解锁
流程:在执行事务之前,先监控我们save数据的值,在执行完事务期间,save数据值没有发生改变则执行事务成功!如果另一个线程在此期间对我们的save值发生了修改,于我们监测(watch)到的值不一致那么就修改失败!
127.0.0.1:6379> set money 10
watch money #在执行事务的时候,先监测money这个值。
OK
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379> decrby k1 1 #修改k1的值
QUEUED
127.0.0.1:6379> exec #执行事务
(nil) #如果money 这个值还是10的时候,将执行成功;如果不是,则放回null