Redis 知识点
redis的全称为远程字典服务器
Redis中文网中Redis的介绍:
1. 为什么使用Redis
- redis是一种内存字典,访问速度远快于访问磁盘
- 随着文件变大,一个data page默认4k,这意味着在没有一个类似B+树的索引时查找一个大文件中的磁盘数据需要的寻址时间变长
- 随着访问量增加和需要取出的数据量变大磁盘I/O变大,而磁盘带宽有限
- 关系型数据库必须给出schema类型(字节宽度)以利于存储,因此倾向于行级存储,而字典则没有这个要求
- redis和memchche最大的区别是redis的value有类型概念(计算向数据移动),这样数据可以不由客户端处理,且可以按需获取数据,且redis在一定程度上支持事务
由上可得,redis可以作为一种变化频率很小的磁盘数据的中间缓存,在大量请求访问该数据时直接从redis内存中返回,降低磁盘数据库压力;同时它也可以直接当作内存数据库使用,也可以借由其队列等作为消息中间件来使用
2. Linux从源码安装Redis
如已经通过yum安装则需要先卸载
yum remove redis
安装命令步骤
#下载软件包
cd ~/soft_package
wget http://download.redis.io/releases/redis-6.0.6.tar.gz
#解压到当前目录,并进入
tar zxvf redis-6.0.6.tar.gz
cd redis-6.0.6
#查看README.md获取帮助 (vim支持markdown)
vim README.md
#编译
make
#1.直接安装redis到默认目录/usr/local/bin; You can use `make PREFIX=/some/other/directory install` if you wish to use a different destination.
make install
#2.通过工具安装redis
cd utils
./install_server.sh
启动redis
#拷贝配置文件
cd /etc
mkdir redis
cp ~/soft_package/redis-6.0.6/redis.conf /etc/redis/
#修改配置文件
vim redis.conf
#进入编辑模式
i
#关闭保护模式以支持远程连接
protected-mode no
#以后台方式启动
daemonize yes
#在做测试时暂时关闭自动持久化
save ""
#开启密码验证
requirepass Redis6379
#esc=>保存
:wq
#启动Redis
redis-server /etc/redis/redis.conf
cli连接redis
#查看cil帮助
redis-cli --help
#连接redis,并使用密码(这种方式不安全)
redis-cli -a Redis6379
3. 常用命令和数据结构
redis是key-value结构
redis的键值都是二进制安全的
常用的value结构及其命令:
1. STRING
String包含了字符型,数值型,和bitmaps
#cli命令行帮助
help @string
字符类型常用命令
#设置键值
SET key value [EX seconds|PX milliseconds] [NX|XX] [KEEPTTL]
#取回键值
GET key
#获取字符串长度
STRLEN key
#当键值不存在时设置键值,常用于当作分布式锁,等同于:SET key value NX
SETNX key value
#一次设置多个键值
MSET key value [key value ...]
#一次获得躲着键值
MGET key [key ...]
#获得key对应的字符串value的子串,这个子串是由start和end位移决定的(两者都在string内)
GETRANGE key start end
#如果key已经存在,并且值为字符串,那么这个命令会把value追加到原来值(key)的结尾,否则就类似于SET
APPEND key value
使用Redis实现分布式锁
#当键值不存在时设置键值,并伴有30000ms过期时间,执行成功的进程获得锁,反之没有获得锁
SET resource_name my_random_value NX PX 30000
#当前锁是否为还被自己持有,如果值为自己给出去的随机值则表示还为自己持有
GET resource_name
#删除键值即可释放锁
DEL resource_name
使用Redis实现可过期的缓存
#设置一个在60秒后过期的键值
SET key_cache value_in_cache EX 60
#获得缓存内容
GET key_cache
#清除缓存
DEL key_cache
数值类型常用命令
#设置键值,此时该值类型时string
SET key value
#自加1,第一次做数值操作时会转换并记录其类型,但其存储未发生改变
INCR key
#自加increment
INCRBY key increment
#自减1
DECR key
#自减decrement
DECRBY key decrement
bitmap类型常用命令
bitmap就是一个可以操作每一个Bit位的值类型,常用于做二进制开关或者以极小的内存统计用户的每日签到情况(每天仅占1个Bit位)
bitmap最短为一个字符,最大为String类型Vlaue的最大大小(512M)
#设置或者清空key的value(字符串)在offset处的bit值。value只能是0或者1
SETBIT key offset value
#返回key对应的string在offset处的bit值
GETBIT key offset
#直接Get时会返回对应值对应编码的字符串,当offset超出了字符串长度的时候,这个字符串就被假定为由0比特填充的连续空间
GET key
#统计字符串被设置为1的bit数,使用复数时从末尾开始计数
BITCOUNT key [start end]
#对一个或多个保存二进制位的字符串key进行位元操作,并将结果保存到destkey上,operation包括:AND,OR,NOT,XOR
BITOP operation destkey key [key ...]
2. HASH
Redis中的Hash类型和常规的Hash集合类似
#cli命令行帮助
help @hash
常用Hash类型命令
#设置key指定的哈希集中指定字段的值,key不存在时会创建哈希集,现在HSET和HMSET没有区别了
HSET key field value [field value ...]
#获取key所在集合的filed的value
HGET key field
#获取key所在集合的多个filed的value
HMGET key field [field ...]
#获得key指定的哈希集中所有的字段和值
HGETALL key
#获取key所在集合的filed的value的长度
HSTRLEN key field
#增加key指定的哈希集中指定字段的数值
HINCRBY key field increment
#只在key指定的哈希集中不存在指定的字段时,设置字段的值
HSETNX key field value
3. LIST
Redis中的List类和常规的List集合类似
List可以当作栈或队列使用
#cli命令行帮助
help @list
常用List类型命令
#设置index位置的list元素的值为value,需要key存在,且index不能超过list的长度
LSET key index value
#将所有指定的值插入到存于key的列表的头部
LPUSH key value [value ...]
#同上,但操作尾部
RPUSH key value [value ...]
#只有当key已经存在并且存着一个list的时候,在这个key下面的list的头部插入value
LPUSHX key value
#移除并且返回key对应的list的第一个元素
LPOP key
#同上但操作最后一个元素
RPOP key
#删除列表中的最后一个元素,将其追加到另一个列表
RPOPLPUSH source destination
#从存于key的列表里移除前count次出现的值为value的元素
LREM key count value
#返回存储在key的列表里指定范围内的元素,下标从0开始,负数时从最后一个开始
LRANGE key start stop
#删除,并获得该列表中的第一元素,或阻塞,直到有一个可用
BLPOP key [key ...] timeout
#同上,但操作的最后一个元素
BRPOP key [key ...] timeout
#修剪到指定范围内的清单
LTRIM key start stop
List做阻塞单播队列
# 生产消息
RPUSH my_queue my_message1
RPUSH my_queue my_message2
# ......
##############
# 消费消息
LPOP my_queue
# ......
4. SET
Redis中的Set类和常规的Set集合类似,不允许出现重复的value
#cli命令行帮助
help @set
常用Set类型命令
#添加一个或多个指定的member元素到集合的 key中.指定的一个或者多个元素member如果已经在集合key中存在则忽略.如果集合key不存在,则新建集合key,并添加member元素到集合key中
SADD key member [member ...]
#在key集合中移除指定的元素,如果指定的元素不是key集合中的元素则忽略
SREM key member [member ...]
#获得队列中不存在的元素
SDIFF key [key ...]
#返回集合存储的key的基数 (集合元素的数量)
SCARD key
#返回key集合所有的元素
SMEMBERS key
5. SORTED_SET
可以按照得分排序的Set
#cli命令行帮助
help @sorted_set
4, 发布订阅模式
发布订阅模式,可以作为消息中间件
#cli命令行帮助
help @pubsub
常用发布订阅模式命令
#订阅给指定频道的信息
#一旦客户端进入订阅状态,客户端就只可接受订阅相关的命令SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE和PUNSUBSCRIBE除了这些命令,其他命令一律失效。
SUBSCRIBE channel [channel ...]
#指示客户端退订给定的频道,若没有指定频道,则退订所有频道
UNSUBSCRIBE [channel [channel ...]]
#将信息message发送到指定的频道channel
PUBLISH channel message
5. Redis事务
MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务相关的命令。事务可以一次执行多个命令, 并且带有以下两个重要的保证:
- 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
- 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
EXEC 命令负责触发并执行事务中的所有命令:
- 如果客户端在使用 MULTI 开启了一个事务之后,却因为断线而没有成功执行 EXEC ,那么事务中的所有命令都不会被执行。
- 另一方面,如果客户端成功在开启事务之后执行 EXEC ,那么事务中的所有命令都会被执行。
事务用法
#开启事务
MULTI
#事务中的命令
SET K1 0
INCR K1
GET K1
#执行事务
EXEC
#开启事务
MULIT
#事务内命令
SET K2 233
#放弃事务,并情况事务内的命令(不执行)
DISCARD
利用Redis事务实现乐观锁CAS
WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为
SET K1 0
#监控k1
WATCH k1
INCR k1
#如果在WATCH和EXEC之间的时间内有其他操作者更改了看k1则事务失败,当不断重复这个过程时就实现了CAS
EXEC
6. Redis持久化
7. Redis集群
1. 集群相关理论
单机的缺陷:
- 单点故障
- 容量有限
- 压力大
集群AKF拆分原则
- X轴(水平扩展)=> 全量,镜像
- X轴(纵向扩展)=> 按业务/功能拆分
- Z轴(数据分区)=> 将XY轴再分区细分
集群CAP理论:
- 一致性(Consistency)
- 可用性(Avilable)
- 分区容错性(Tolerance of network Partition)
- 三者不可同时满足
当强一致性时,势必需要更多的开销甚至强制同步阻塞,从而降低可用性,反之亦然;
而Redis集群更强调可用性,大多数情况下只要求满足最终一致性即可,作为缓存时也可以容忍一部分的数据丢失
Redis在主从复制时采用了异步复制,这意味这在实际中集群在特定的条件下可能会丢失写操作.复制时fork了一个线程,并在这个线程中完成复制,linux的fork实现了Copy-On-Write因此执行效率高内存开销相对小.
2. Redis集群介绍
-
Redis 集群是一个提供在多个Redis间节点间共享数据的程序集
-
Redis集群并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误
-
Redis 集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令. Redis 集群的优势:
- 自动分割数据到不同的节点上
- 整个集群的部分节点失败或者不可达的情况下能够继续处理命令
3. Redis 集群的数据分片
Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:
- 节点 A 包含 0 到 5500号哈希槽.
- 节点 B 包含5501 到 11000 号哈希槽.
- 节点 C 包含11001 到 16384号哈希槽.
这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态.
3. Redis Cluster
#搭建集群时需要的最少配置redis.conf
#单个实例PORT
port 6381
#开实例的集群模式
cluster-enabled yes
#设定了保存节点配置文件的路径,它由Redis集群在启动时创建,并在有需要时自动进行更新
cluster-config-file nodes.conf
#超时时间
cluster-node-timeout 5000
#启用AOF
appendonly yes
要让集群正常运作至少需要三个主节点,因此分别按照端口创建文件夹6381,6382,6383,并在其中创建redis.conf写入上面的配置