文章目录
Redis 简介
是完全开源的,使用C语言编写的,遵守BSD协议,是一个高性能的(key-value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库
- Redis支持数据的持久化,可以将内存中的数据库保存在磁盘中,重启的时候可以再次加载进行使用
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list、set、zset、hash等数据结构的存储
- Redis支持数据的备份,即master-slave模式的数据备份
下载安装
中文网站:http://www.redis.cn/download.html
英文网站:https://redis.io/download
-
下载、解压、编译Redis
$ wget http://download.redis.io/releases/redis-6.0.6.tar.gz $ tar xzf redis-6.0.6.tar.gz $ cd redis-6.0.6 $ make
-
由于可能系统上没有 gcc 在make这一步时就会报错
-
使用
yum install gcc-c++
安装 gcc,完成后使用gcc -v
出现版本号查看版本号需要5.3以上,否则#升级到 5.3及以上版本 yum -y install centos-release-scl yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils scl enable devtoolset-9 bash #注意:scl命令启用只是临时的,退出xshell或者重启就会恢复到原来的gcc版本。 #如果要长期生效的话,执行如下: echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
-
先 使用
make distclean
命令清除上次make失败的文件和目录,再次make安装完成 -
进入redis的src文件夹下
cd /opt/environment/redis-6.0.6/src/
使用./redis-server
指令启动redis- 此时启动为前台启动,它停留在了redis的启动页面,无法执行其他命令
- 使用后台启动
./redis-server &
指令按回车即可
启动 Redis服务
由于 redis 默认并不会加载自己的配置文件,所以当我们对配置文件进行了修改时,每次启动则需要带上配置文件的地址
- 可以进入redis的安装目录的src下/使用
./redis-server redis.conf &
启动服务 - 也可以使用绝对路径开启服务
/opt/environment/redis-6.0.6/src/redis-server /opt/environment/redis-6.0.6/redis.conf &
关闭 Redis服务
使用redis客户端关闭,向服务器发出关闭指令
-
切换到redis-6.0.6/src/目录,执行
./redis-cli shutdown
进行关闭-
推荐使用这种方式,redis先完成数据操作,然后再关闭
-
方式二:使用进程关闭命令
kill <pid>
或者kill -9 <pid>
强行关闭
Redis 客户端
命令行客户端
redis-cli 是Redis 自带的基于命令行的Redis 客户端,用于与服务端交互,我们可以使用该客户端来执行redis的各种命令
方式一:
- 在redis 安装目录/src/目录下执行
./redis-cli
命令- 此命令是连接本机127.0.0.1,端口6379的redis
方式二:
- 指定IP 和端口连接 redis:
./redis-cli -h <ip地址> -p <端口号>
远程客户端
使用前提:
-
在防火墙中配置 6379端口,对这个端口放行
firewall-cmd --zone=public --add-port=6379/tcp --permanent
- 重启防火墙服务
systemctl restart firewall.service
-
远程连接redis需要修改redis主目录下的redis.conf配置文件
-
bind ip 绑定ip此行注释
-
protected-mode yes 保护模式改为no
-
先使用
cp redis.conf bak_redis.conf
命令将redis.conf 配置文件备份 -
使用
vim redis.conf
命令进入配置文件修改如下图两处位置 -
重新启动redis 并指定配置文件;进入redis的src/目录下使用
./redis-server ../redis.conf &
-
-
使用远程客户端进行连接
-
因为我们redis还没有设置密码,所以上图 Auth 不用填写直接连接
编程客户端
Redis 基本操作命令
当操作数据库时,出现如下图,是因为redis 默认设置了定时将数据存储到磁盘中,以免数据丢失
沟通、查看
ping
:沟通命令,查看状态- 使用命令后,redis给我们返回PONG,表示redis服务运行正常
dbsize
:返回当前数据库的key的数量- 默认是查索引为0的库,可以先使用
select <库索引>
命令先指定库再进行查看
- 默认是查索引为0的库,可以先使用
默认库
redis默认使用16个库,索引从0到15,对数据库的个数的修改,在redis.conf文件中
databases 16
可以直接进行修改
删除与退出
flushdb
:删除当前数据库quit
andexit
:都可以退出redis客户端
Redis 关于Key的命令
查找指定 Key
keys [pattern]
:查找所有符合模式pattern的key; pattern可以使用通配符- *:表示0-多个字符,列如:key * 查询所有的 key
- ?:表示单个字符,例如:wo?d,配置所有的以wo开头d结尾的字符
判断是否存在
exists key [key...]
:判断key是否存在- 返回值:整数,存在key返回1,其他返回0,使用多喝key,返回存在的key的数量
设置生存时间
expire key [seconds]
:设置key的生存时间,超过时间key自动销毁,单位是秒- 返回值:设置成功返回数字1,其他情况是0
查看生存时间
ttl key
:以秒为单位,返回key的剩余生存时间- 返回值:-1:没有设置key的生存时间。key永不过期
- 返回值:-2:key不存在
- 返回值:number:key的剩余时间,秒为单位
查看数据类型
-
tpe key
:查看key所存储值的数据类型返回值:
- none:key不存在
- string:字符串
- list:列表
- set:无序不重复集合
- zset:有序不重复集合
- hash:哈希表
删除指定 key
del key [key...]
:删除指定的一个key或多个key- 返回值:数值,删除的key的数量
5种数据类型
-
string
-
字符串类型是 Redis 中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据、序列化后的数据、JSON对象、甚至是一张图片,最大内存为512M
-
hash
-
Redis hash 是一个string类型的 field 和 value 的映射表,hash 特别适合用于存储对象
Map<String,String> data = new HashMap<>(); data.put("username","zhangsan"); //此时的key 称为 field data.put("times","5"); data.put("region","北京"); Map<String,Map<String,Object>> map = new HashMap<>(); //此时的key 在redis中就是真正的key map.put("loginUser",data); //此时这个map 就是redis 中的 hash 类型
-
-
list
- Redis 列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边)
-
set
- Set 是 string类型的无序集合,集合成员是唯一的,即集合中不可能出现重复的数据
-
zset
- 有序集合zset 和集合 set 一样也是string类型元素的集合,且不重复,不同的是zset的每一个元素都会关联一个分数(分数可以重复),redis通过分数来为集合中的成员进行从小到大排序
数据类型的操作命令
在 Redis 中 对于每种数据类型都有专属的执行命令
string
基本命令
set key value
:在当前数据库中创建一个字符串的 key 和 valueget key
:获取指定key对应的value,如果没有则返回 nilincr key
:将指定key的value进行+1并返回操作- 如果value并不是integer,那么会报错
- 如果指定的 key 不存在,那么会自动创建一个 key 并赋初值为“0”
decr key
:与 incr 相反,将指定 key 的value 进行-1操作,其属性与 incr 相同append key value
:将value值追加到指定key的value值的末尾并返回value值的长度- 如果key不存在,则创建指定的 key-value数据
常用命令
strlen key
:返回指定key所存储的字符串值的长度- key 不存在则返回0
getrange key start end
:截取指定key中 start 到 end 直接的子串,是双闭的- 下标从0开始
- 负数表示从字符串的末尾开始, -1表示最后一个字符
- 使用getrange取出所有的value:
getrange key 0 -1
setrange key offset value
:使用value覆盖指定key的value值,从offset开始mset key value [key value...]
:同时创建一个或多个key-value 数据,成功返回OKmget key [key...]
:同时获取多个key对应的value值,结果按先后顺序排列若没有key 返回 nil
hash
基本命令
-
hset key field value
:将哈希表 key 中的域 field 的值设为 value,如果 key 不存在,则创建新的 hash 表进行赋值,如果有 field则进行覆盖操作返回值:
- field 是 hash 表中的新 field,且设置值成功,返回 1
- field 已经存在,新值覆盖旧值,返回 0
-
hget key field
:获取一个hash对应的field值,没有返回 nil -
hmset key field value [field]
:同时创建一个或多个field-value 设置到哈希表中- 如果 field存在,则进行覆盖操作
- 当 hash表的 key不存在时,则创建一个空的 hash 表 执行 hmset 命令,设置成功返回 ok
- 目前 redis 版本直接使用 hset命令 就可以实现
-
hmget key field [field...]
:返回 hash 表 key 中 对应的一个或多个 field 的值- 返回的值为一个列表 与输入的 field 一一对应,若某个field 不存在 则使用 nil 填充
-
hgetall key
:获取哈希表 key 中所有的 域和值,以列表的形式返回,key不存在,返回空 hash -
hdel key field [field...]
:删除 hash 中指定的一个或多个 field,如果field 不存在,则直接忽略,返回成功删除的field的数量
常用命令
hkeys key
:返回 hash 表中所有的field 值hvals key
:返回 hash 表中field 所有的value 值hexists key field
:判断 hash 表中指定key的 field值是否存在- 存在返回1,否则返回0
list
list添加元素时可以指定头部和尾部,所以当一些命令以 [l]开头表示指向的头部(左边),而以[r]开头表示指向尾部(右边)
基本命令
lpush key value [value...]
:将一个或多个 value 插入到列表 key 的表头(最左边)lpush mylist a b c
:此时列表排列顺序是 c b arpush mylist a b c
:此时列表的顺序是 a b c
lrange key start stop
:取出从下标以start开始到stop结束的元素lrange key 0 -1
:取出全部元素
lindex key index
:取出list中key 指定下标的元素,没有返回 nilllen key
:返回list的长度,返回则返回0
常用命令
-
lrem key count value
:根据参数count的值,删除列表中与参数 value 相同的元素,成功返回修改个数- count > 0:从列表的左侧向右开始移除
- count < 0:从列表的尾部开始移除
- count = 0:移除表中所有与value相等的值
- 这个 count 可以决定删除的方向
-
lset key index value
:将列表 key 下标为 index 的元素替换为 value,成功返回OK -
linsert key BEFORE|ALFTER pivot value
:将值value 插入到列表 key 当中位于值 pivot 之前或之后的位置, key 不存在,pivot 不在列表中,不执行任何操作- 返回值:命令执行成功,返回新列表的长度,没有找到 pivot 返回 -1 ,key不存在返回 0
set
基本命令
sadd key member [member]
:将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略,不会再加入- 返回值:加入到集合的新元素的个数,不包括被忽略的元素
smembers key
:获取集合 key 中的所有成员元素,不存在的 key 视为空集合sismember key member
:判断 member 元素是否是集合 key 的成员- 返回值: member 是集合成员返回 1 其他返回 0
scard key
:返回 key 元素长度srem key member [member]
:删除集合 key 中的一个或多个 member 元素,不存在的元素被忽略- 返回值:数字,成功删除的元素个数,不包括被忽略的元素
常用命令
-
srandmember key [count]
:只提供 key,随机返回集合中一个元素,当提供了 count 时
- count > 0,返回包含 count 个数元素的集合,集合元素各不相同
- count < 0,返回一个 count 绝对值的长度的集合,集合中元素可能会重复多次
-
spop key [count]
:随机从集合中删除一个元素,count 是删除的元素个数,count 不能为负数- 返回值:被删除的元素, key 不存在或空集合返回 nil
zset
基本命令
-
zadd key score member [score member...]
:将一个或多个 member 元素及其 score 值加入到有序集合 key 中,如果member 存在集合中,则将原则覆盖, score 可以是整数或者浮点数- score:按照 score 值进行升序,score 可以重复,
- 当 score 值重复时先按照value值的第一个字母排序,如果第一个字母相同时,比较第二个以此类推
-
zrange key start stop [WITHSCORES]
:查询有序集合,指定区间的内的元素,集合成员按score值从小到大来排序- start和stop 都是从0开始,0是第一个元素,1是第二个元素,以 -1 表示最后一个元素
- WITHSCORES 选项返回值是 score 和 value
-
zrevrange key start stop [withsores]
:返回有序集合 key 中,指定区间内的成员,成员的位置按 score 值的降序排列,其他属性与zrange相同 -
zrem key member [member...]
:删除一个或多个集合 key 中 指定 member -
zcard key
:获取有序集合 key 的元素成员个数- 返回值: key 存在返回集合元素的个数,key 不存在,返回 0
常用命令
-
zrangebyscore key min max [withscores] [LIMIT offset count]
:获取有序集合 key 中,所有 score 值,介于 min 和 max 之间(闭区间)的成员,有序成员是按升序排序- min,max 如果使用符号 ( 表示不包括 min, max
- 可以使用 -inf,+inf 表示最小和最大,相当于负无穷和正无穷
- limit:用来限制返回结果的数量和区间
-
zrevrangebyscore key min max [withscores] [LIMIT offset count]
:- 返回有序集 key 中mscore 值介于max 和min 之间(闭区间),有序集按score 值的降序依次排列,其他属性与 zrangebysocre 相同
-
zcount key min max
:返回有序集 key 中,score 值再 min 和max 之间(闭区间)的成员数量
Redis 事务
事务是指一系列操作步骤。这一系列的操作步骤要么完全地执行,要么完全地不执行。Redis 事务(transaction)是一组命令的集合,至少是两个以上的命令,red 事务保证这些命令被执行时中间不会被任何其他操作打断,而redis 没有回滚操作
事务操作的命令
-
multi
:标记一个事务的开始。事务内的多条命令会按照先后顺序被放进一个队列当中,返回值总是返回 OK -
exec
:执行所有事务块内的命令;返回值:事务内的所有执行语句内容,事务被打断(影响)返回 nil -
discard
:取消事务,放弃执行事务块内的所有命令,总是返回ok -
watch
:监视一个或多个事务,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断 -
unwatch
:取消 WATCH 命令对所有 key 的监视- 如果在执行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被执行了话,那么就不需要再执行 UNWATCH了
-
事务执行exec命令后,执行队列命令,命令执行错误,事务提交
- MULTI 正常命令
- SET username zhangsan 正常命令
- lpop username 正常命令,语法没有错误,执行命令时才会报错
- exec 正常执行,发现错误可以在事务提交前放弃事务,执行 discard
Redis 的 WATCH 机制
WATCH 机制原理
- WATCH机制:使用 WATCH 监视一个或多个 key,跟踪key的value修改情况,如果有 key的 value 值在事务 EXEC执行之前被修改了,整个事务被取消。EXEC 返回提示信息,表示事务已经失败。
- WATCH 机制使得事务 EXEC 变的有条件,事务只有在被 WATCH 的 key 没有修改的前提下才能执行。不满足条件,事务被取消。使用 WATCH 监视了一个带过期时间的键,那么即使这个键过期了,事务依然可以正常执行
- 大多数情况下,不同的和护短会访问不同的键,相互同时竞争同一key的情况一般都很少,乐观锁能够以很好的性能解决数据冲突的问题
何时取消 key 的监视(WATCH)?
持久化
持久化可以理解为存储,就是将数据存储到磁盘,如果把数据放在内存中,电脑关闭或重启数据就会丢失,所以放在内存中的数据不是持久化的,而放在磁盘就算是一种持久化。
Redis 的数据存储在内存中,内存是瞬时的,如果linux宕机或重启,又或者 Redis 崩溃或重启,所有的内存数据都会丢失,为解决这个问题, Redis 提供两种机制对数据进行持久化存储,便于发生故障后能迅速恢复数据。
RDB 方式
Redis Database(RDB),就是在指定的时间间隔内将内存中的数据集快照写入磁盘,数据恢复时将快照文件直接再读到内存。
RDB 保存了在某个时间点的数据集(全部数据)存储在一个二进制文件中,只有一个文件。默认是dump.rdb。RDB技术非常适合做备份,可以保存最近一个小时,一天,一个月等的全部数据,存储数据是在单独的进程中写文件,不影响 Redis 的正常使用。RDB 恢复数据时比其他 AOF 速度快。
实现方式:
在配置文件redis.conf 中搜索 SNAPSHOTTING,查找在注释开始和结束直接的关于 RDB的配置说明。配置 SNAPSHOTTING 地方有三处。
- 配置执行 RDB 生成快照文件的时间策略
- 对 Redis 进行设置,让它在“N秒内数据至少有M个 key 改动”这一条件被满足时,自动保存一次数据集
- 配置格式:
save <seconds> <changes>
- save 900 1
- save 300 10
- save 60 10000
- dbfilename:设置 RDB的文件名,默认文件名为 dump.rdb
- dir:指定 RDB 文件的存储位置,默认是 ./ 当前目录
配置步骤:
-
查看
ps -ef|grep redis
,如果redis服务启动,先停止服务 -
修改redis.conf文件,修改前先备份,执行
cp redis.conf bak_redis.conf
-
重启服务即可
总结:
优点:由于存储的是数据快照文件,恢复数据很方便,也比较快
缺点:
- 会丢失最后一次快照以后更改的数据。如果你的应用能容忍一定的数据丢失,那么使用rdb是不错的选择;如果你不能容忍一定数据的丢失,使用rdb就不是一个很好的选择。
- 由于需要经常操作磁盘, RDB 会分出一个子进程。如果你的 Redis 数据库很大的话,子进程占用比较多的时间,并且可能会影响 Redis 暂停服务一段时间(millisecond 级别),如果你的数据库超级大并且你的服务器CPU比较弱,有可能是会达到一秒。
AOF 方式
Append-only File (AOP),Redis 每次接受到一条改变数据的命令时,它将把该命令写到一个 AOF文件中,当 Redis 重启时,它通过执行 AOF 文件中所有的命令来恢复数据
如何实现:
AOF 方式的数据持久化,仅需在 redis.conf 文件中配置即可
- appendonly:默认是 no,改成 yes即开启了 aof 持久化
- appendfilename:指定 aof 文件名,默认文件名为 appendonly.aof
- dir:指定 RDB 和 AOF文件存放的目录,默认是./
- appendfsync:配置向aof文件写命令数据的策略:
- no:不主动进行同步操作,而是完全交由操作系统来做(即每30秒一次),比较快但不是很安全。
- always:每次执行写入都会执行同步,慢一些但是比较安全
- everyesc:每次执行一次同步操作,比较平衡,介于速度和安全之间。这是默认项
- auto-aof-rewrite-min-seze:允许重写的最小 AOF 文件大小,默认是 64M,当 aof 文件大于 64M 时,开始整理 aof 文件,去掉无用的操作命令。缩小aof 文件
操作步骤:
主从复制
Redis 主从复制实现
- 方式一:修改配置文件,启动时,服务器读取配置文件,并自动成为指定服务器的从服务器,从而构成主从复制的关系
- 方式二:
./redis-server --slaveof <master-ip> <master-port>
在启动时指定当前服务器成为某个主 Redis服务的从Slave - 方式一的实现步骤:模拟多 Redis 服务器,在一台已经安装Redis的机器上,运行多个 Redis 应用模拟多个 Redis服务器,一个Master,两个 Slave
编辑 Master 配置文件
编辑 Master 的配置文件 redis6380.conf:在空文件加入如下内容
include /opt/environment/redis-6.0.6/redis.conf
daemonize yes
port 6380
pidfile /var/run/redis_6380.pid
logfile 6380.log
dbfilename dump6380.rdb
配置项说明:
- include:包含原来的配置文件内容 ,/opt/environment/redis-6.0.6/redis.conf 按照自己的目录设置
- daemonize:yes 后台启动应用,相当于 ./redis-server &,这个 & 的作用
编辑 Slave 配置文件
编辑 Slave 的配置文件 redis6381.conf 和 redis6382.conf:在空文件加入如下内容
-
redis6381.conf
-
include /opt/environment/redis-6.0.6/redis.conf daemonize yes port 6381 pidfile /var/run/redis_6381.pid logfile 6381.log dbfilename dump6381.rdb slaveof 127.0.0.1 6380
-
配置项说明:
- slaveof:表示当前 Redis 是谁的从,当前是127.0.0.1 端口是6380 这个 Master 的从
启动服务:
-
src/redis-server redis6380.conf
-
src/redis-server redis6381.conf
-
src/redis-server redis6382.conf
-
然后使用
src/redis-cli -p 6380
启动主服务器,启动后可以通过info replication
查看信息 -
使用另外一个窗口再启动一个客户端
src/redis-cli -p 6381
,启动后使用info replication
查看信息- up/down:说明是上线状态,down说明已经挂掉了
-
在主服务器上添加数据,从服务器同时也能得到和主服务系统的数据结构,但是使用从服务器添加数据时报错,不能写,只能读数据
容灾处理
冷处理
当 Master 服务出现故障,需手动将slave 中的一个提升为 master,剩下的 slave 挂至新的 master 上(冷处理:机器挂掉了,再处理)
命令:
slaveof no one
:将一台 slave 服务器提升为 Master- 告诉别的从,新主是谁:
slaveof 127.0.0.1 6381
:将 slave挂至新的 master上
恢复
src/redis-server redis6380.conf
:启动服务器;src/redis.cli -p 6380
:启动客户端- 此时,恢复的服务器认为自己是主,需要告诉它,现在已经有新主,使用
slaveof 127.0.0.1 6381
挂至新的 master 即可
高可用 Sentinel 哨兵
Sentinel 哨兵是 redis 官方提供的高可用方案,可以用它来监控多个 Redis 服务实例的运行情况。 Redis Sentinel 是一个运行再特殊模式下的 Redis 服务器,Redis Sentinel 是在多个Sentinel进程环境下互相协作工作的,哨兵个数只能是奇数
Sentinel 系统有三个主要任务:
- 监控:Sentinel 不断检查主服务和从服务器是否按预期正常工作
- 提醒:被监控的 Redis出现问题时,Sentinel 会通知管理员或其他应用程序
- 自动故障转移:监控的主 Redis不能正常工作,Sentinel 会开始进行故障迁移操作,将冷处理的操作步骤进行自动化
哨兵配置文件
-
配置自己的端口号
-
配置开始的 master 端口号和票数
哨兵执行
src/redis-sentinel sentinel26381.conf
:启动一个哨兵src/redis-sentinel sentinel26382.conf
src/redis-sentinel sentinel26383.conf
当主服务器发生宕机,或崩溃时,哨兵发现进行投票,然后再自己选举一个认为性能较好的slave变成 master
服务器修好后,重启服务器,哨兵会自动将此服务器挂至到他们新选举的 master上,变为 slave
使用 info replication
进行检查
安全设置
设置密码
Redis 默认是没有密码的,任意用户都可以访问,我们可以开启使用密码才能访问Redis ,设置Redis 的访问密码,修改redis.conf中requirepass密码。密码要比较复杂,不容易破解,而且需要定期修改,因为redis速度相当快,所以一台比较好的服务器下,一个外部的用户可以在一秒钟进行 150K次的密码尝试,需要指定非常非常强大的密码来防止暴力破解
开启访问密码设置
vim redis.conf
修改配置文件,找到requirepass 去掉注释,requirepass 空格后就是密码- 启动客户端时
src/redis-cli -a password
即可,或者先进入客户端之后 使用auth password
,否则即使进入客户端了也没有任何权限
绑定 ip
修改 redis.conf 文件,把 # bind 127.0.0.1 前面的注释 # 去掉,然后把127.0.0.1改成允许访问你redis服务器的ip 地址,表示只允许该ip进行访问,多个ip使用空格分隔
修改默认端口号
修改 redis的端口,这一点 很重要,使用默认的端口非常危险,redis.conf中修改port6379将其修改为自己指定的端口(可随意范围在1024-65535)端口1024是保留给操作系统使用的
修改默认端口后,启动客户端使用src/redis-cli -p newPort
Jedis 操作 Redis
使用 Redis 官方推荐的 Jedis,在Java应用中操作 Redis,Jedis 几乎涵盖了 Redis的所有命令,操作 Redis 的命令在 Jedis中以方法的形式出现。
下载:
- 可以直接取Maven中央仓库搜索 jedis即可
- 由于jedis 是线程不安全的所以一般配合 Commons-Pool 线程池的方式一起使用
- 效率和安全性更高
使用前提:
- 配置远程访问ip 或者注释掉
- 配置防火墙开启对端口号的放行,或者关闭防火墙
更多详细操作 参考https://my.oschina.net/HJCui/blog/751842