Redis --- 缓存(键值型NoSQL)

全称:REmote DIctionary Server
历史:意大利人Salvatore Sanfilippo,2009年开源了Redis,从2010年起,Redis的开发工作由VMware主持,从2013年开始,Redis的开发由Pivotal赞助
官网:https://redis.io/
Windows版Redis:https://github.com/MicrosoftArchive/redis

同类产品对比
Memcache:数据类型单一,只有String
淘宝 Tair:单节点性能较低,社区不活跃

Linux安装Redis
1、官网上下载 redis.tar.gz;上传到 /usr;tar -zxvf redis.tar.gz
2、进入redis安装目录,make
3、redis.conf 设置 bind 0.0.0.0;protected-mode no
4、启动:/usr/redis/src/redis-server /usr/redis/redis.conf ,必须显示指定配置文件,否则配置文件不生效
5、新起shell,使用客户端:/usr/redis/src/redis-cli
6、检查接口监听:netstat -tunlp | grep 6379
7、测试时确保外部能访问,设置云主机安全组规则,扫描6379端口是否开放

原理
单线程

数据类型

String:字符串、整数、浮点数
List:以String为节点的双向链表
Set:String 不重复集合
zSet:有序集合
Hash:Map
HyperLogLog:基数

客户端命令

清空:flushdb
查看匹配的key:keys *
切换db:select 2 // 客户端默认打开的是第0个db,一共16个db
===================== String ====================
设值:set key value
取值:get key
删值:del key
值长:strlen key
取值然后设值:getset key value
获取子串:getrange key start end
追加:append key value
加一:incr key
加整数:incrby key int
减一:decr key
减整数:decrby key int
加浮点数:incrbyfloat key float

=================== Hash =======================
单字段设值:hset key filed value
非空字段设值:hsetnx key field value
多字段设值:hmset key field1 value1 field2 value2
多字段取值:hmget key field1 field2
取所有键:hkeys key
取所有值:hvals key
取所有键值:hgetall key
取字段数量:hlen key
是否存在键:hexists key field
删除字段:hdel key field1 field2
字段加整数:hincrby key field int
字段加浮点数:hincrbyfloat key field int

==================== List ======================
左侧操作
从左侧加入节点:lpush key node1 node2
非空链表加入节点:lpushx key node
在node0前插入节点:linsert key before node0 node
在node0后插入节点:linsert key after node0 node
设置节点:lset key index node
获取指定节点:lindex key index
获取多个节点:lrange list start end
获取链表长度:llen key
弹出一个节点:lpop key
删除count个小于等于value的节点:lrem key count value
剪切链表,保留start到stop:ltrim key start stop

右侧操作
rpush key node1 node2
rpushx list node
rpop key

阻塞操作
blpop key timeout:lpop没节点时,阻塞直到有节点 或 timeout

==================== Set ======================
增加元素:sadd key member1 member2
转移成员:smove src des member
获取元素数量:scard key
获取差集:sdiff key1 key2
保存差集:sdiffstore des key1 key2
获取交集:sinter key1 key2
保存交集:sinterstore des key1 key2
获取并集:sunion key1 key2
保存并集:sunionstore des key1 key2
获取所有成员:smembers key
随机弹出一个成员:spop key
是否包含:sismember key member
移除元素:srem key member1 member2

==================== ZSet ======================
非顺序相关操作
获取元素数量:zcard key
元素加整数:zincrby key int member
保存交集:zinterstore desKey 2 key1 key2
保存并集:zunionstore desKey 2 key1 key2

顺序相关操作
添加元素:zadd key score1 value1 score2 value2
获取分数值在范围内的元素:zcount key (min max]
获取成员值在范围内的元素:zlexcount key [min max)
获取多个元素:zrange key start end
删除分数值在范围内的元素:zremrangebyscore key min max
删除成员值在范围内的元素:zremrangebylex key min max
删除多个元素:zremrangebyscore key start end
获取成员分数值:zscore key member

====================== 事务 =======================
监听数据:watch key1 key2 // 被监听的数据在下面的事务执行前发生变化,则事务不执行
解除监听:unwatch key1 key2
开启事务:multi
执行事务:exec // 会解除先前的监听
放弃事务:discard // 会解除先前的监听

乐观锁:非阻塞锁,即不阻塞其他线程,同时又能一定程度上保证数据一致性,可以用CAS机制实现
CAS:compare and swap,解决多线程情况下使用锁造成性能损耗的一种机制;一个线程,要改变一个数据前,先比较他的当前值和先前值,不一致则放弃修改
ABA问题:CAS机制下,一个数据先前值为A,当前值也为A,前后一致,被认为未变化;单有可能是变化了两次A->B->A
Redis解决ABA问题:每条数据附带有一个version,检查version是否变化

======================= 发布 与 订阅 =====================
在一个客户端订阅:subscribe channel_1
在另一个客户端发布:publish channel_2

========================= 超时时间 ======================
设置超时时长:expire key seconds // 单位为秒
设置超时时长:pexpire key milliseconds // 单位为毫秒
设置超时时间点:expireat key timestamp // 单位为秒
设置超时时间点:pexpireat key stamptimes // 单位为毫秒
查看超时设置:ttl key // 单位为秒
查看超时设置:pptl key milliseconds // 单位为毫秒
取消超时设置:persist key
惰性回收:超时后再调用一次get才真正被回收

配置

位置:安装目录/redis.conf
AOF模式持久化:Append-Only File,记录所有写操作
LRU算法:在多个样品中找到使用最少的样品
TTL算法:在多个样品中找到剩余存活时间(离超时)最短的样品

requirepass  "abcdefg"  # 需要密码
# 进行持久化,即启动Redis server时,会读取持久化文件作为初始数据
save 900 1   # 当900 秒执行1 个写命令时,进行持久化
save 300 10 # 当300 秒执行10 个写命令时,进行持久化
save 60 10000 # 当60 秒内执行10000 个写命令时,进行持久化
# 把所有save注释掉,则不进行持久化
dbfilename dump.rdb  # 快照持久化文件
appendonly no # 是否用AOF模式持久化,代替快照模式
appendfilename "appendonly.aof"  # AOF持久化文件

## 内存不足还要写入时的数据淘汰策略
maxmemory-samples 5   # LRU算法或TTL算法 的样品数量
maxmemory-policy  noeviction # 不淘汰
maxmemory-policy  volatile-ttl # TTL淘汰数据
maxmemory-policy  volatile-random # 随机淘汰超时数据
maxmemory-policy allkeys-random # 随机淘汰任意数据
maxmemory-policy volatile-lru # LRU淘汰超时数据
maxmemory-policy allkeys-lru # LRU淘汰任意数据

主从复制

1、配置redis.conf

bind 0.0.0.0  # 允许任何IP访问,主从服务器都设置
slaveof server port  # 初始master,从服务器设置

2、用命令改变本slave的master
slaveof server port

哨兵模式 Sentinel

1、mater,只负责写

bind 0.0.0.0

2、slave,只负责读

bind 0.0.0.0
slaveof server port   # 初始master
masterauth pass1    # master的密码

3、配置哨兵 sentinel.conf
哨兵进程的启动脚本也在redis的安装包内,一台主机上可以同时启动redis-server进程 和 redis-sentinel进程
主观下线:一个sentinel发现mater宕机
客观下线:一个sentinel发起投票,确认master宕机,通知所有sentinel切换master

protected-mode no  # 关闭保护模式,让外界可访问
# sentinel monitor 主服务器名 ip port 确认master宕机的最低得票数
sentinel monitor mymaster ip port 2  # 要监听本机的redis,不能用127.0.0.1,否则会使Spring访问自己所在的主机
sentinel auth-pass mymaster pass1

4、启动
进程启动顺序:master server -> slave server -> sentinel
启动哨兵进程:/usr/redis/src/redis-sentinel /usr/redis/sentinel.conf

代理模式

Twitter公司出品的Twemproxy,可作为Redis的代理

集群模式

与哨兵模式的区别:主节点有多台,从节点分别追随一个主节点,主节点自带哨兵,来下线故障的节点;优点:多节点可写;缺点:网络IO较频繁
分片功能:所有的key被分到16384个槽位slot中,分槽的hash函数为 crc16(key)%16384,多个主节点平分16384个槽。数据操作请求随机分发给一个主节点,当数据的key所属的槽不在这个节点,则通知请求方去请求正确的主节点

redis集群搭建
1、安装多个(以6个为例)单节点 redis,配置开启集群功能 cluster-enabled yes,并启动
2、选取一个节点用来运行ruby脚本以初始化集群
安装ruby:yum install -y ruby
安装rubygems:yum install -y rubygems,ruby包管理工具
安装redis.gem:gem install redis
3、初始化集群:/usr/redis/src/redis-trib.rb create --replicas 1 IP_1:端口 IP_2:端口 IP_3:端口 IP_4:端口 IP_5:端口 IP_6:端口
4、用客户端连接集群:redis/src/redis-cli -h 127.0.0.1 -p 7001 -c
5、连接集群后,查询集群状态:cluster info;cluster nodes;此时已经分片好了(分配好了槽位)

分片方案

1、客户端分片:性能好,实现简单,已定位问题;侵入业务
2、代理分片:成本增加,性能降低
3、集群分片

阿里云

云数据库 Redis 版

你可能感兴趣的:(Redis --- 缓存(键值型NoSQL))