Redis概念【了解】
Redis安装配置【掌握】
Redis数据类型<font color=red>【重点】</font>
Redis通用key操作命令【掌握】
Redis key 设计技巧<font color=red>【重点】</font>
解析配置文件 【掌握】
Redis扩展【会用】
一、redis概念
1、Redis概念
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。
Redis 与其他 key - value 缓存产品有以下三个特点:
-
Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
-
Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
-
Redis支持数据的备份,即master-slave模式的数据备份。
2、Redis优势
-
性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
-
丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
-
原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
-
丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性
3、Redis与其他key-value存储有什么不同
-
Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
-
Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,应为数据量不能大于硬件内存。在内存数据库方面的另一个优点是, 相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。 同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
二、安装配置Redis
1、下载redis
redis官网:https://redis.io
redis中文官网:https://www.redis.net.cn/download/
2、安装windows版redis
将windows版redis解压
双击redis-server.exe启务redis服务端
双击redis-cli.exe启动redis客户端
-
使用redis命令测试redis,向redis中存值
-
取出redis中保存的值
3、安装Linux版redis
-
上传redis到linux中
将资料中linux版的redis上传到linux的/usr/local/目录下
-
解压redis
tar -zxvf redis-5.0.4.tar.gz
-
修改redis目录名
mv redis-5.0.4 redis5 -
编译redis
进入到tedis5目录中执行:
make
如果出现如下错误,则需要安装gcc c++编译器
yum install gcc-c++
出现下图则表示安装成功
-
检查是否安装成功
语法:make install -
启动redis
编译成功后,到redis/src中启动redis服务
-
使用redis客户端连接redis
在xhell中新开一个命令窗口
4、linux启动redis
redis默认是前台进程,开启后窗口就不能做其他事情,可以将redis设为后台进程。
-
复制redis5/redis.conf到/usr/local/bin目录中
-
修改redis.conf文件将里面的daemonize no 改成 yes,让服务在后台启动
-
启动Redis:/usr/local/bin目录下运行redis-server,运行拷贝出存放了自定义conf文件目录下的redis.conf文件
-
开启服务 redis-server redis.conf
-
配置redis远程访问
redis默认只能本机访问
bind 0.0.0.0 //该配置表示所有机器都可以访问redis
修改redis的守护进程为no 不启用(上面已经配置过,不用管)
daemonize no
修改redis的保护模式为no,不启用
protected-mode no
-
开启客户端:
redis-cli -h xxx.xxx.xxx -p 6379
参数说明:
-h:redis服务器的ip地址
-p:redis的访问端口 -
关闭redis的服务
shutdonw
exit -
查看redis进程
ps –ef |grep redis<font color=red> 注:单实例关闭:redis-cli shutdown ,多实例关闭,指定端口关闭:redis-cli -p 6379 shutdown</font>
5、redis目录说明
- redis-benchmark:性能测试工具,可以在自己本子运行,看看自己本子性能如何,服务启动起来后执行
- redis-check-aof:修复有问题的AOF文件,rdb和aof后面讲
- redis-check-dump:修复有问题的dump.rdb文件
- redis-cli:客户端,操作入口
- redis-sentinel:redis集群使用
- redis-server:Redis服务器启动命令
6、Redis启动后杂项基础讲解
-
默认数据库的数量
默认16个数据库,类似数组下表从零开始,初始默认使用零号库,设置数据库的数量,默认数据库为0,可以使用SELECT <<dbid>命令在连接上指定数据库id databases 16)
-
dbsize查看当前数据库的key的数量,直接输入keys * 也可以查看当前数据库key的数量
-
flushdb:清空当前库
-
Flushall;通杀全部库
三、Redis数据类型
1、redis五大数据类型
redis存储的是:key,value格式的数据,其中key都是字符串,value有5种不同的数据结构
value的数据结构:
1) 字符串类型 string
2) 哈希类型 hash : map格式
3) 列表类型 list : linkedlist格式。支持重复元素
4) 集合类型 set : 不允许重复元素
5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序
2、String类型
String(字符串)string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M
<font color=red>如果 key 已经持有其他值, SET 就覆写旧值,无视类型。</font>
a、常见基本指令
set username zhangsan //将值zhangsan保存到键username中
get username //取出键username的值
append username feng //将值feng追加到键username中
strlen username //获得字符串的长度
案例:演示Stirng类型基本指令
b、数字指令
数字指令是用来对数字进行数学计算的
set k 2 //将2保存到键k1中
操作整数
incr k //将键k的值自增1
incrby k 3 //将k的值与3相加,当键后的值为小数时报错
decrby k 2 //将k的值与2相减
incrbyfloat key 3.14 //将k的值与3.14相加
案例:演示Stirng类型的数字指令
c、范围指令
范围指令
getrange username 0 -1 //获得键username中所有的值
setrange username 0 abc //从第一个位置开始将abc替换三个字符
getrange:获取指定区间范围内的值,类似between......and的关系从零到负一表示全部setrange设置指定区间范围内的值
setrange:修改key对应的值,从值的开始下标开始,连续几个字符被替换
案例:演奏示String范围指令
d、key过期指令
在创建key时可以设置该key的过期时间
语法:
set key value [ex 秒数] / [px 毫秒数] [nx] /[xx]
如: set a 1 ex 10 , 10秒有效
Set a 1 px 9000 9秒有效
注: 如果ex,px同时写,以后面的有效期为准。
如 set a 1 ex 100 px 9000 实际有效期是9000毫秒
nx: 表示key不存在时,执行操作
xx: 表示key存在时,执行操作
<font color=blue>案例:创建key并设置key的有效期为10秒</font>
创建key并设置key的有效期为10秒,10秒后再查询
e、设置多个key-value
mset:同时设置一个或多个 key-value 对,mget:获取所有(一个或多个)给定 key 的值。
msetnx:同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在
mset k1 v1 k2 v2 k3 v3
mget k1 k2 k3
msetnx k1 v11 k2 v22 k3 v33 //无效,因为k1 \ k2 \k3都存在
3、Hash类型
Hash(哈希)Redis hash 是一个键值对集合。Redis hash是一个string类型的field和value的映射表,<font color=red>hash特别适合用于存储对象。类似Java里面的Map<String,Object></font>
<font color=red>在hash类型中,也是一个键值对,key不变 v又是一个键值对</font>
a、hash基本命令
命令:
hset : 写入元素到集合
hget:获取集合key的值
hmset:批量给value写入值
hmget: 批量获得key的值
hgetall获取某个key的所有value
hdel:删除hash中某个键值对
hlen:获取hashsize
示例:
hset user id 1 //创建一个键名称为:user,值中有一个键 id
hget user id //取出user键中id属性的值
hmset user2 id 2 username 张三 sex 男 //创建一个键名称为:user2,值中有三个键 id username sex
hmget user2 id username //获得user2中id和username属性的值
hgetall user //获得user2键中所有属性的值
hdel user2 id //删除user2键中的id属性
hlen user2 //获得user2键的大小
案例一:为一个value赋值
案例二:一次为多个value赋值
案例三:查看键中所有的值
案例四:删除和获得键的大小
b、has![](https://img2020.cnblogs.com/blog/2586506/202111/2586506-20211103175210688-1390675669.png)
h判断与查看命令
命令:
hexists 判断某个key 对应的value中的 某个key是否存在
Hkeys 命令用于获取哈希表中的所有域(field)。
hvals命令 获取哈希表中所有值。
示例:
hexists user address // 判断key是user的值中 是否含有address的键
hvals user //查看key是user中所有的值
hkeys user //查看key是user中所有的key
案例:演示判断与查看命令
c、数字指令
命令:
hincrby:为哈希表 key 中的指定字段的整数值加上增量 increment。
hincrbyfloat: 为哈希表 key 中的指定字段的浮点数值加上增量 increment 。
示例:
hincrby user age 2 //为key为user中的age加2
hincrbyfloat user age 3.56 //为key为user中的age加3.56
4、List类型
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
a、添加元素到List命令
命令:
lpush 向左添加元素
rpush 向右添加元素
lrange 显示集合元素
语法:lrange key start end
Llen 获取集合的长度
示例:
lpush mylist 小花 小黑 //向key为mylist中向左边添加两个值
rpush mylist 小白 小黄 //向key为mylist中向右边添加两个值
lrange mylist 0 -1 //显示key为mylist中的值,0表示从第一个无素开始 -1表示到最后一个结束,可以替换为具体下标
llen mylist //显示key为mylist的长度
b、根据下标操作与删除命令
命令:
lset 通过索引来设置元素的值。
语法:LSET KEY_NAME INDEX VALUE
lindex 按照根据下标找出对应的元素,下标从0开始
lpop key: 删除列表最左边的元素,并将元素返回
rpop key: 删除列表最右边的元素,并将元素返回
示例:
lset mylist 1 张三 //在下标为1的位置插入张三
lindex mylist 2 //取出key为mylist中下标为2的元素
lpop mylist //删除key为mylist中最左边的元素
rpop mylist //删除key为mylist中最右边的元素
List性能总结:
它是一个字符串链表,left、right都可以插入添加;如果键不存在,创建新的链表; 如果键已存在,新增内容;如果值全移除,对应的键也就消失了。链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就很惨淡了。
5、Set类型
在list中是允许保存重复的元素的,因为没有键,当元素重复后就搞不清楚哪个值是需要的
Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
a、添加与查询命令
命令:
sadd 添加元素到set集合中
语法sadd key value
smembers 显示集合内容
语法:smembers key
sismember 判断集合中是否有某个元素
语法: sismember key value
scard 获取集合里面的元素的个数
语法: scard key
Srandmember 返回集合中的一个随机元素。从 Redis 2.6 版本开始, Srandmember 命令接受可选的 count 参数
- 如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合基数,那么返回整个集合。
- 如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值
示例:
sadd myset tom jack woniu //向myset中添加三个值
smembers myset //显示myset中的内容
scard myset //获得myset中的元素个数
sismember myset tom //判断myset中是否有tom元素
b、删除元素命令
命令:
srem :删除集合中的某个元素
语法:srem key value
Smove 命令将指定成员 value 元素从 key1 集合移动到 key2 集合
语法:smove key1 key2 value
示例:
srem myset admin //删除myset中的admin元素
smove myset1 myset2 jack //将key1中的jack元素移动到myset2中
6、zset类型(sorted set:有序集合)
Sorted set有序集合,和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
命令:
zdd 向有序集合添加一个或多个成员,或者更新已存在成员分数
语法:zadd key score value
zadd 集合名称 分数(随便给) 值
zrange 通过索引区间返回有序集合成指定区间内的成员
语法:zrange key startIndex endIndex
zrem 移除有序集合中的一个或多个成员
语法:zrem key value1 value2 value3 ...
zscore 返回有序集合中某个成员的分数值
语法:zscore key value
zcount 计算在有序集合中指定区间分数的成员个数
语法:zcount key min max
zrank 返回有序集合中指定成员的索引
语法:zrank key value
zrevrange 返回有序集中指定区间内的成员,通过索引,分数从高到低
语法:zrevrange key startIndex endIndex
zrevrangebyscore 返回有序集中指定分数区间内的成员,分数从高到低排序
语法:zrevrangebyscore key max min
示例:
zadd myzset 40 tom 10 jack 30 admin 50 woniu //创建有序set myzset,为其添加三个分数与对应的值
zrange myzset 0 -1 //显示集合中所有的值
zrem myzset admin //移除admin
zscore myzset jack //显示jack的分数
zcount myzset 10 30 //显示集合中的成员个数
zrank myzset woniu //显示值为woniu的下标
zrevrange myzset 0 -1 //将集合中的元素根据下标,将分数从高到低显示
zrevrangebyscore myzset 40 10 //将集合中的元素根据分数从高到低排序显示
四、Redis通用key操作命令
查询所有key
语法:keys *
删除1个或多个指定key
语法:del key1 key2 ... Keyn
作用: 删除1个或多个键
返回值: 不存在的key忽略掉,返回真正删除的key的数量
修改key名称
语法:rename key newkey
作用: 给key赋一个新的key名
提示:如果newkey已存在,则newkey的原值被覆盖
查询相应key
在redis里,允许模糊查询key,有3个通配符 *, ? ,[]
*: 通配任意多个字符
?: 通配单个字符
[]: 通配括号内的某1个字符
语法:keys pattern 查询相应的key
示例:
keys ??? //查询长度为三个字符的key
keys t[abc] //查询以t开头后面为指定"abc"中的任意一个
keys t* //查询以t开头的key
随机返回一个key
语法::randomkey
判断key是否存在
语法:exists key
示例:exists mylist //判断mylist是否存在 key存在返回1,不存在返回0
判断key中值的类型
语法:type key
返回key存储的值的类型string,link,set,order set, hash
查询key的生命周期
语法:ttl key
作用: 查询key的生命周期
返回: 秒数
注:对于不存在的key或已过期的key/不过期的key,都返回-1。Redis2.8中,对于不存在的key,返回-2
移动键到其他redis数据库
一个redis进程,打开了不止一个数据库, 默认打开16个数据库,从0到15编号,如果想打开更多数据库,可以从配置文件修改
切换redis数据库使用select 编号
切换到1号数据库:切换到1号数据库后,之前保存的数据都没有了(redis默认使用0号数据库)
select 1
设置key的有效期
语法:expire key 整型值
作用: 设置key的生命周期,以秒为单位
同理:
pexpire key 毫秒数, 设置生命周期
pttl key, 以毫秒返回生命周期
设置key为永久有效
语法:persist key
刷新数据库
在redis中执行刷新数据库操作后,redis中保存的数据将会被清空。
语法:flushdb
五、Redis key 设计技巧
怎样将mysql数据表与redis的key对y应?
步骤:
1: 把表名转换为key前缀 如, tag:
2: 第2段放置用于区分区key的字段--对应mysql中的主键的列名,如userid
3: 第3段放置主键值,如2,3,4...., a , b ,c
4: 第4段,写要存储的列名
语法:
set user:userid:9:username lisi
set user:userid:9:password 111111
set user:userid:9:email lisi@163.com
根据主键查询数据
<font color=red>注意:在关系型数据中,除主键外,还有可能其他列也需要查询,如上表中, username 也是极频繁查询的,往往这种列也是加了索引的。转换到k-v数据中,则也要相应的生成一条按照该列为主的key-value</font>
<font color=blue>案例 :配置redis中根据用户名查询信息</font>
语法:Set user:username:lisi:uid 9
将要做为查询的条件设为索引
根据用户名查出对应的id
然后根据id查出该用户其他信息
六、解析配置文件 redis.conf
1、Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程daemonize no
2、redis的计量单位 units单位配置大小单位,开头定义了一些基本的度量单位,只支持bytes,不支持bit,对大小写不敏感
3、includes 和我们的Struts2配置文件类似 包含其他的子模块,struts配置文件的拆分s,可以通过includes包含,redis.conf可以作为总闸,包含其他redis配置文件
4、当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定pidfile /var/run/redis.pid
5、指定Redis监听端口,默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字 port 6379
6、当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能 timeout 300
7、绑定的主机地址 bind 127.0.0.1
8、tcp-keepalive 单位为秒,如果设置为0,则不会进行Keepalive检测,建议设置成60,意思是60秒没有对redis做任何操作,则断开
9、loglevel verbose 日志级别, Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
10、logfile stdout 日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null
11、databases 16 设置数据库的数量,默认数据库为0,可以使用SELECT 命令在连接上指定数据库id
12 SNAPSHOTTING快照
save 秒钟 写操作次数,RDB是整个内存的压缩过的Snapshot,RDB的数据结构,可以配置复合的快照触发条件,默认是1分钟内改了1万次,或5分钟内改了10次,或15分钟内改了1次。如果想禁用RDB持久化的策略,只要不设置任何save指令,或者给save传入一个空字符串参数也可以
save 900 1
save 300 10
save 60 10000
分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。
13、rdbcompression yes 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
14、 rdbchecksum yes 在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
15、dbfilename dump.rdb 指定本地数据库文件名,默认值为dump.rdb
16、dir ./ 指定本地数据库存放目录
17、 SECURITY安全 可以给redis登陆设置密码
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin"
127.0.0.1:6379> config set requirepass "123"
OK
127.0.0.1:6379> ping
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth 123
OK
127.0.0.1:6379> ping
PONG
18、LIMITS限制
maxclients 128 设置redis同时可以与多少个客户端进行连接。默认情况下为10000个客户端。当你无法设置进程文件句柄限制时,redis会设置为当前的文件句柄限制值减去32,因为redis会为自身内部处理逻辑留一些句柄出来。如果达到了此限制,redis则会拒绝新的连接请求,并且向这些连接请求方发出“max number of clients reached”以作回应。
maxmemory 设置redis可以使用的内存量。一旦到达内存使用上限,redis将会试图移除内部数据,移除规则可以通过maxmemory-policy来指定。如果redis无法根据移除规则来移除内存中的数据,或者设置了“不允许移除”,那么redis则会针对那些需要申请内存的指令返回错误信息,比如SET、LPUSH等。但是对于无内存申请的指令,仍然会正常响应,比如GET等。如果你的redis是主redis(说明你的redis有从redis),那么在设置内存使用上限时,需要在系统中留出一些内存空间给同步队列缓存,只有在你设置的是“不移除”的情况下,才不用考虑这个因素
maxmemory-policy 过期策略
(1) volatile-lru:使用LRU算法移除key,只对设置了过期时间的键
(2) allkeys-lru:使用LRU算法移除
(3) volatile-random:在过期集合中移除随机的key,只对设置了过期时间的键
(4) allkeys-random:移除随机的
(5)volatile-ttl:移除那些TTL值最小的key,即那些最近要过期的key
(6)noeviction:不进行移除。针对写操作,只是返回错误信息
lru :least recently user缓存过期清洁策略
maxmemory-samples 设置样本数量,LRU算法和最小TTL算法都并非是精确的算法,而是估算值,所以你可以设置样本的大小, redis默认会检查这么多个key并选择其中LRU的那个
19 、appendonly no 指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no
20、appendfilename appendonly.aof 指定更新日志文件名,默认为appendonly.aof
21、appendfsync everysec 指定更新日志条件,共有3个可选值
no:表示等操作系统进行数据缓存同步到磁盘(快)always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)everysec:表示每秒同步一次(折衷,默认值)
22、include /path/to/local.conf 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
七、Redis扩展
1、配置redis以后台进程的形式运行
每次启动redis服务端后窗口都不能关闭,关闭客户端就连接不上,可以通过修改redis.conf配置文件让redis在后台运行,<font color=red>将redis.conf中的daemonize修改为yes,保存后重新启动服务端即可</font>
2、关闭redis
语法:shutdown
3、redis密码配置
现在只要知道redis的地址谁都可以连接上,可以为redis设置密码,连接时能过密码认证,找到redis-config中的 #requirepass foobared 去掉注释,修改密码 -> requirepass yourpassword
<font color=red>注意:修改密码后不能直接关闭redis进程,也不能直接退出,要使用shutdown命令退出redis</font>
4、清空Redis
语法:
//删除当前数据库中的所有Key
flushdb
//删除所有数据库中的key
flushall