【Redis】

一、Redis简介

1.1 什么是Redis

1.1.1 Redis简介

Redis(Remote Dictionary Server):即远程字典服务,是一个开源的、采用ANSI C语言编写,基于内存的且支持持久化,高性能的Key-Value的NoSQL数据库。Redis将数据写入内存,不需要通过I/O流读取数据,效率较高。

Redis官网:https://redis.io/

1.1.2 NoSQL的概念

NoSQL(Not Only SQL):泛指非关系型的数据库,区别于关系数据库,它们不保证关系数据的ACID特性。

  • 那什么是非关系型数据库?

要说非关系型数据库我们首先要了解什么是关系型数据库了;我们之前使用的MySQL就是一个典型的关系型数据库。我们知道,MySQL是一款数据库存储系统;我们操作的步骤是先建立数据库再建立表,表是由行和列组成的二维表格模型;在这个表中,列之间是存在关系的;
如下图所示,一张user表:

我们可以看到MySQL的一张表中,除了存储我们的数据之外,外维护着列与列、行与行之间的数据关系;
除此之外,我们知道表之间是存在关系的,一对一、一对多、多对多等:

在关系型数据库中,除了存储我们的数据之外,还很大程度上维护了我们数据之间的关系;
非关系数据库则不存储数据之间的关系,存储数据简单,只关心如何存取,不去维护数据之间的关系;Redis正是非关系型数据库中的一款热门产品;

1.2 Redis的特点

在项目中使用Redis,主要是从两个角度去考虑:性能并发,这是当前互联网发展过程中首要考虑的两个重难题。当然除去这两个要点之外,Redis还具备可以做分布式锁、任务队列等其他额外功能,此外Redis还易于扩展、支持丰富的数据类型存储。
经官方性能测试Redis的读速度是110000次/s,写速度能够达到81000次/s 。非常适用于当前高并发、高性能的实际业务场景;

1.2.1 性能

Redis是基于内存级别的缓存,这样使得请求能够快速从缓存中得到响应。相比传统请求数据库,响应速度大幅度提高。
但需要注意的是,引入了Redis后我们的项目架构将会发生一定的变化;如下图所示,我们在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取
引入Redis之前的项目架构:

引入Redis之后,项目架构的变化:

1.2.2 并发

如下图所示,在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用redis做一个缓冲操作,并且Redis支持高性能的主从复制的集群策略,这样大大提高满足高并发访问及快速响应。请求优先访问到redis请求数据,从而避免高并发情况下直接访问数据库。
引入Redis之前的项目架构:

引入Redis之后,项目架构的变化:

此外,Redis支持丰富的数据结构;如:字符串(strings),散列(hashes),列表(lists),集合(sets),有序集合(sorted sets)与范围查询,bitmaps,hyperloglogs和地理空间(geospatial)索引半径查询。
并且Redis丰富的支持主流语言的客户端,C、C++、Python、Erlang、R、C#、Java、PHP、Objective-C、Perl、Ruby、Scala、Go、JavaScript

1.3 安装部署Redis

Redis官方只开发了基于Linux平台的Redis服务,是没有支持Windows系统的,但是微软自己就做了一个支持win64位系统的,并将其发布到了Github;
Redis Windows版本下载地址:https://github.com/microsoftarchive/redis/releases

1.3.1 Redis命令介绍

下载好Redis,我们将其解压:

  • redis-server:Redis服务
  • redis-cli:Redis客户端
  • redis-windows.conf:Redis配置文件

  • 启动Redis服务:


双击redis-cli命令打开客户端窗口:

1.3.2 Redis服务常用配置

常用配置命令:

  • port:指定端口
  • database:数据库的数量
  • logfile:Redis的日志文件名
  • dir:设定当前服务文件保存位置,包含日志文件、持久化文件等
  • requirepass:设置当前Redis服务的密码
  • timeout:客户端连接的超时时间,单位:秒

配置文件示例:
port 6379 # 配置端口 databases 16 # 数据库的数量 logfile .\data\redis-6379.log # Redis产生的日志文件名称 dir D:\Redis-x64-3.2.100\data # Redis运行产生的数据文件夹 requirepass admin # 连接Redis服务的密码 timeout 5 # 客户端连接的超时时间是5s bind 0.0.0.0 # 允许任意客户端来连接该redis服务器
Tips:Redis的配置文件中不能编写中文,连注释也不行

1.3.3 Redis客户端配置

常用配置命令:

  • -h:服务器的地址
  • -p:服务器的端口
  • -a:服务器的密码

1)使用默认连接配置
./redis-cli
2)指定参数启动
./redis-cli -h 127.0.0.1 ./redis-cli -p 6379 ./redis-cli -h 127.0.0.1 -p 6379 -a admin

1.4 RDM可视化工具

Redis Desktop Manager:简称RDM;是一款支持跨平台的可视化数据库管理工具,基于Qt 5开发,支持命令控制台操作以及常用查询、修改、删除等操作,可快速轻松地创建、编辑和删除所有数据库对象,具有完善全面的数据操作功能;

官网:https://rdm.dev/
使用RDM连接Redis服务:

连接成功:

二、Redis数据类型

2.1 String数据类型

2.2.1 String基本操作

  • String类型数据结构如下:

89.png

  • set:存数据
    • 格式:
SET key value
  • 示例:
WindowsServer:0>set name zhangsan
"OK"
WindowsServer:0>
  • get:取数据
    • 格式:
GET key
  • 示例:
WindowsServer:0>get name
"zhangsan"
WindowsServer:0>
  • del:删除数据
    • 格式:
DEL key [key ...]
  • 示例:
WindowsServer:0>del name
"1"
WindowsServer:0>
  • mset:一次性存储多个key
    • 格式:
MSET key value [key value ...]
  • 语法:
WindowsServer:0>mset a zhangsan b lisi c wangwu
"OK"
WindowsServer:0>
  • mget:一次性取多个key
    • 格式:
MGET key [key ...]
  • 语法:
WindowsServer:0>mget a b c
1) "zhangsan"
2) "lisi"
3) "wangwu"
WindowsServer:0>
  • strlen:获取字符个数
    • 格式:
STRLEN key
  • 语法:
WindowsServer:0>strlen a
"8"
WindowsServer:0>
  • append:追加字符串(如果没有则新增)
    • 格式:
APPEND key value
  • 语法:
WindowsServer:0>append a 88
"10"
WindowsServer:0>
  • setnx:存入key,如果这个key存在则返回0(false),代表存入失败,如果不存在则返回1(true),代表存入成功;
    • 格式:
setnx key value
  • 语法:
WindowsServer:0>setnx flag 0
"1"
WindowsServer:0>setnx flag 0
"0"
WindowsServer:0>

2.2.2 自增自减操作

  • 自增:
    • 语法:
incr key
  • 格式:
WindowsServer:0>set num 10
"OK"
WindowsServer:0>incr num
"11"
WindowsServer:0>
  • 控制步长自增:
    • 语法:
incrby key increment
  • 格式:
WindowsServer:0>incrby num 10
"21"
WindowsServer:0>
  • float类型自增:
    • 格式:
incrbyfloat key increment		# 自增小数
  • 语法:
WindowsServer:0>set num2 0.5
"OK"
WindowsServer:0>incrbyfloat num2 0.5
"1"
WindowsServer:0>incrbyfloat num2 0.5
"1.5"
WindowsServer:0>
  • 自减
    • 语法:
decr key
  • 示例:
WindowsServer:0>set num 10
"OK"
WindowsServer:0>decr num
"9"
WindowsServer:0>decr num
"8"
WindowsServer:0>
  • 控制步长自减:
    • 语法:
decrby key increment
  • 示例:
decrby a 10

2.2.3 控制时效性

  • 语法:
setex key seconds value		# 秒

psetex key milliseconds value		# 毫秒
  • 示例:
WindowsServer:0>setex name 5 zhangsan
"OK"
WindowsServer:0>psetex name 5000 zhangsan
"OK"
WindowsServer:0>

2.2 Hash数据类型

  • hash类型的存储结构如下:

88.png

hash类型的数据结构,底层采用hash表存储。

1.2.1 hash基本操作

  • hset:添加/修改数据
    • 格式:
HSET key field value
  • 示例:
WindowsServer:0>hset user username zs
"1"
WindowsServer:0>hset user password admin
"1"
WindowsServer:0>
  • hegt:添加/修改数据
    • 格式:
HGET key field
  • 示例:
WindowsServer:0>hget user username
"zs"
WindowsServer:0>
  • hdel:删除数据
    • 格式:
HDEL key field [field ...]
  • 示例:
WindowsServer:0>hdel user password
"1"
WindowsServer:0>
  • hmset:一次性添加/修改多个字段
    • 格式:
HMSET key field value [field value ...]
  • 示例:
WindowsServer:0>hmset user username zs password admin age 20
"OK"
WindowsServer:0>
  • hmget:一次性取多个数据
    • 格式:
HMGET key field [field ...]
  • 示例:
WindowsServer:0>hmget user username password age
1) "zs"
2) "admin"
3) "20"
WindowsServer:0>
  • 获取指定key的field的数量
    • 格式:
HLEN key
  • 示例:
WindowsServer:0>hlen user
"3"
WindowsServer:0>
  • hexists:判断指定的key中是否包含有指定的field(返回1[有]或0[没有])
    • 格式:
HEXISTS key field
  • 示例:
WindowsServer:0>hexists user username
"1"
WindowsServer:0>hexists user xxx
"0"
WindowsServer:0>

1.2.2 hash扩展操作

  • hkeys:获取key中所有的field
    • 格式:
HKEYS key
  • 示例:
WindowsServer:0>hkeys user
1) "username"
2) "password"
3) "age"
WindowsServer:0>
  • hvals:获取key中所有的value
    • 格式:
HVALS key
  • 示例:
WindowsServer:0>hvals user
1) "zs"
2) "admin"
3) "20"
WindowsServer:0>
  • hgetall:获取指定key中所有的field以及value值
    • 格式:
HGETALL key
  • 示例:
WindowsServer:0>hgetall user
1) "username"
2) "zs"
3) "password"
4) "admin"
5) "age"
6) "20"
WindowsServer:0>
  • hsetnx:如果指定key中有对应的field则返回0(false),如果没有则存对应的值进去
    • 格式:
HSETNX key field value
  • 示例:
WindowsServer:0>hsetnx user flag 1
"1"
WindowsServer:0>hsetnx user flag 1
"0"
WindowsServer:0>

2.3 List数据类型

在Redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。Redis中的list类型采用的是双向链表。

Redis存储结构如下:

87.png

2.3.1 list基本操作

  • 添加/修改数据
    • 格式:
LPUSH key value [value ...]		# 添加到队列左侧
RPUSH key value [value ...]		# 添加到队列右侧
  • 示例:
WindowsServer:0>lpush fruits apple pear
"2"
WindowsServer:0>rpush fruits banana tomato
"4"
WindowsServer:0>

fruits链表的变化如下:

86.png

  • 获取数据
    • 格式:
LRANGE key start stop		# 从左边开始读取数据,从start索引查询到stop索引
  • 示例:
WindowsServer:0>lrange fruits 0 3	# 从0开始查询到3索引
1) "pear"
2) "apple"
3) "banana"
4) "tomato"
WindowsServer:0>lrange fruits 0 -2	# 从0开始查询到-2索引
1) "pear"
2) "apple"
3) "banana"
WindowsServer:0>lrange fruits 0 -1	# 从0开始查询到-1索引(倒数第二),通常用此命令来查询全部数据
1) "pear"
2) "apple"
3) "banana"
4) "tomato"
WindowsServer:0>
  • 根据指定的索引查询(从0开始)
    • 格式:
LINDEX key index
  • 示例:
WindowsServer:0>lindex fruits 3
"tomato"
WindowsServer:0>

Tips:lindex不支持反向查询

  • 获取并移除数据
    • 格式:
LPOP key		# 从队列左边移除一个元素并返回

RPOP key		# 从队列右边移除一个元素并返回
  • 示例:
WindowsServer:0>lpop fruits
"pear"
WindowsServer:0>rpop fruits
"tomato"
WindowsServer:0>

2.3.2 list扩展操作

  • 规定时间内获取并移除数据
    • 格式:
BLPOP key [key ...] timeout		# 在timeout时间内取出key中的值
BRPOP key [key ...] timeout
  • 示例:
WindowsServer:0>blpop fruits 3
1) "fruits"
2) "apple"
WindowsServer:0>blpop fruits 3
1) "fruits"
2) "banana"
WindowsServer:0>blpop fruits 3		# 3秒内取出fruits中的值并删除,如果没取到则一直处于等待状态

WindowsServer:0>
  • 规定时间内移除list右边的一个元素到另一个list的左边,并将此元素返回
    • 格式:
BRPOPLPUSH source destination timeout
  • 示例:
WindowsServer:0>flushdb			# 清空数据库
"OK"
WindowsServer:0>lpush fruits apple
"1"
WindowsServer:0>lpush fruits pear
"2"
WindowsServer:0>brpoplpush fruits temp 3
"apple"
WindowsServer:0>lrange temp 0 -1
1) "apple"
WindowsServer:0>brpoplpush fruits temp 3
"pear"
WindowsServer:0>lrange temp 0 -1
1) "pear"
2) "apple"
WindowsServer:0>lrange fruits 0 -1 # fruits链表中已经没有了数据

WindowsServer:0>
  • 移除指定数据
    • 格式:
LREM key count value		# 从list左边开始移除元素
  - count:移除多少个
  - value:移除什么元素
  • 示例:
WindowsServer:0>rpush data a b c d e a b c k o
"10"
WindowsServer:0>lrange data 0 -1
1)  "a"
2)  "b"
3)  "c"
4)  "d"
5)  "e"
6)  "a"
7)  "b"
8)  "c"
9)  "k"
10) "o"
WindowsServer:0>lrem data 2 a 
"2"
WindowsServer:0>lrange data 0 -1
1) "b"
2) "c"
3) "d"
4) "e"
5) "b"
6) "c"
7) "k"
8) "o"
WindowsServer:0>

2.4 Set数据类型

在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存在等操作。需要说明的是,这些操作的时间是常量时间。Set可包含的最大元素数是4294967295。

和List类型不同的是,Set集合中不允许出现重复的元素。和List类型相比,Set类型在功能上还存在着一个非常重要的特性,即在服务器端完成多个Sets之间的聚合计算操作,如sintersdiffsunion等操作。由于这些操作均在服务端完成,  因此效率极高,而且也节省了大量的网络IO开销

2.4.1 set基本操作

  • 添加数据
    • 格式:
sadd key member [member ...]
  • 示例:
WindowsServer:0>sadd cities changsha wuhan nanchang hefei hangzhou fuzhou
"6"
WindowsServer:0>
  • 读取全部数据
    • 格式:
smembers key
  • 示例:
WindowsServer:0>smembers cities
1) "nanchang"
2) "wuhan"
3) "changsha"
4) "hefei"
5) "hangzhou"
6) "fuzhou"
WindowsServer:0>

set存取无序;

  • 删除数据
    • 格式:
srem key member [member ...]
  • 示例:
WindowsServer:0>srem cities fuzhou hangzhou
"2"
WindowsServer:0>smembers cities
1) "changsha"
2) "nanchang"
3) "hefei"
4) "wuhan"
WindowsServer:0>
  • 获取集合中元素的个数
    • 格式:
scard key
  • 示例:
WindowsServer:0>scard cities
"4"
WindowsServer:0>
  • 判断集合中是否包含指定的数据
    • 格式:
sismember key member
  • 示例:
WindowsServer:0>sismember cities nanchang
"1"
WindowsServer:0>

2.4.2 set扩展操作

  • 移动集合中的指定元素到另一个集合
    • 格式:
smove source destination member
  • 示例:
WindowsServer:0>sadd fruits1 apple pear
"2"
WindowsServer:0>sadd fruits2 banana tomato
"2"
WindowsServer:0>smove fruits1 fruits2 apple
(integer) 1
WindowsServer:0>smembers fruits1
1) "pear"
WindowsServer:0>smembers fruits2
1) "apple"
2) "banana"
3) "tomato"
  • 在指定的key中随机获取几个值
    • 格式:
srandmember key [count]
  • 示例:
WindowsServer:0>srandmember cities 2
1) "hefei"
2) "changsha"
WindowsServer:0>
  • 在指定的key中随机获取几个值,并将这几个值移除
    • 格式:
SPOP key [count]

count默认为1

  • 示例:
WindowsServer:0>spop cities
"hefei"
WindowsServer:0>smembers cities
1) "changsha"
2) "nanchang"
3) "wuhan"
WindowsServer:0>spop cities 2 
1) "changsha"
2) "wuhan"
WindowsServer:0>smembers cities 
1) "nanchang"
WindowsServer:0>

2.4.3 交集差集并集

82.png

  • 取两个集合的交集:
    • 格式:
sinter key [key ...]			# 交集
  • 示例:
WindowsServer:0>sadd cities1 lanzhou guangzhou fuzhou hangzhou zhengzhou
"5"
WindowsServer:0>sadd cities2 meizhou guangzhou quanzhou fuzhou ganzhou
"5"
WindowsServer:0>sinter cities1 cities2
1) "guangzhou"
2) "fuzhou"
WindowsServer:0>
  • 取两个集合的差集:
    • 格式:
sdiff key [key ...]				# 差集
  • 示例:
WindowsServer:0>sdiff cities1 cities2
1) "zhenghzhou"
2) "hangzhou"
3) "lanzhou"
WindowsServer:0>
  • 取两个集合的并集:
    • 格式:
sunion key [key ...]			# 并集
  • 示例:
WindowsServer:0>sunion cities1 cities2
1) "quanzhou"
2) "meizhou"
3) "zhenghzhou"
4) "lanzhou"
5) "guangzhou"
6) "hangzhou"
7) "fuzhou"
8) "ganzhou"
WindowsServer:0>
  • 获取两个集合的交、差、并集存储到指定集合中
    • 格式:
sinterstore destination key1 [key2]		# 交集
sdiffstore destination key1 [key2]		# 差集
sunionstore destination key1 [key2]		# 并集
  • sinterstore-案例:
WindowsServer:0>sinterstore sinter_temp cities1 cities2
"2"
WindowsServer:0>smembers sinter_temp
1) "guangzhou"
2) "fuzhou"
WindowsServer:0>
  • sdiffstore-案例:
WindowsServer:0>sdiffstore sdiff_temp cities1 cities2
"3"
WindowsServer:0>smembers sdiff_temp
1) "zhenghzhou"
2) "hangzhou"
3) "lanzhou"
WindowsServer:0>
  • sunionstore-案例:
WindowsServer:0>sunionstore sunion_temp cities1 cities2
"8"
WindowsServer:0>smembers sunion_temp
1) "quanzhou"
2) "meizhou"
3) "zhenghzhou"
4) "lanzhou"
5) "guangzhou"
6) "hangzhou"
7) "fuzhou"
8) "ganzhou"
WindowsServer:0>

2.5 Sorted_set数据类型

Sorted-Sets和Sets类型极为相似,它们都是字符串的集合,都不允许重复的成员出现,在一个Set中。它们之间的主要差别是Sorted-Sets中的每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为集合中的成员进行从小到大的排序。然而需要额外指出的是,尽管Sorted-Sets中的成员必须是唯一的,但是分数(score) 却是可以重复的。

2.5.1 sorted_set基本操作

  • 添加数据
    • 格式:
zadd key score1 member1 [score2 member2]
  • 示例:
WindowsServer:0>zadd students 90 xiaohui 80 xiaolan 85 xiaoming 
"3"
WindowsServer:0>
  • 读取数据
    • 格式:
zrange key start stop [WITHSCORES]
zrevrange key start stop [WITHSCORES]
  - `start`:起始索引
  - `stop`:终止索引
  - `withscores`:是否显示分值
  - `zrevrange`:将查询结果反转
  • 示例:
WindowsServer:0>zrange students 0 0
1) "xiaolan"
WindowsServer:0>zrange students 0 1
1) "xiaolan"
2) "xiaoming"
WindowsServer:0>zrange students 0 2
1) "xiaolan"
2) "xiaoming"
3) "xiaohui"
WindowsServer:0>zrange students 0 -1
1) "xiaolan"
2) "xiaoming"
3) "xiaohui"
WindowsServer:0>zrange students 0 -1 withscores			# 默认正序排序
1) "xiaolan"
2) "80"
3) "xiaoming"
4) "85"
5) "xiaohui"
6) "90"
WindowsServer:0>zrevrange students 0 -1 withscores 		# 倒序排序
1) "xiaohui"
2) "90"
3) "xiaoming"
4) "85"
5) "xiaolan"
6) "80"
WindowsServer:0>
  • 根据分值筛选
    • 格式:
zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]
  - min:最小分值(包含)
  - max:最大分值(包含)
  - limit:限定查询结果(分页查询) 
     - offset:起始索引(从0开始)
     - count:查询几条数据
  - zrevrangebyscore:根据分值反转查询
  • 示例:
WindowsServer:0>zrangebyscore students 80 85
1) "xiaolan"
2) "xiaoming"
WindowsServer:0>zrangebyscore students 80 85 withscores 
1) "xiaolan"
2) "80"
3) "xiaoming"
4) "85"
WindowsServer:0>zrangebyscore students 80 85 withscores limit 0 2
1) "xiaolan"
2) "80"
3) "xiaoming"
4) "85"
WindowsServer:0>
  • zrevrangebyscore:根据分值反转查询
WindowsServer:0>zrevrangebyscore students 100 0
1) "xiaohui"
2) "xiaoming"
3) "xiaolan"
WindowsServer:0>zrevrangebyscore students 100 0 withscores
1) "xiaohui"
2) "90"
3) "xiaoming"
4) "85"
5) "xiaolan"
6) "80"
WindowsServer:0>zrevrangebyscore students 100 0 withscores limit 0 2
1) "xiaohui"
2) "90"
3) "xiaoming"
4) "85"
WindowsServer:0>

2.5.2 sorted_set其他操作

  • 根据分值范围查询集合总数量
    • 格式:
zcount key min max
  • 示例:
WindowsServer:0>zcount students 80 85
"2"
WindowsServer:0>
  • 取多个集合中的交集、并集
zinterstore destination numkeys key [key ...]
zunionstore destination numkeys key [key ...]
  • destination:目标集合
  • numkeys:有几个集合需要操作

交集示例:

WindowsServer:0>zadd fruits1 100 apple 80 pear 70 banana
"3"
WindowsServer:0>zadd fruits2 50 apple 60 tomato 70 banana
"3"
WindowsServer:0>zinterstore zinter_temp 2 fruits1 fruits2
"2"
WindowsServer:0>zrange zinter_temp 0 -1
1) "banana"
2) "apple"
WindowsServer:0>zrange zinter_temp 0 -1 withscores
1) "banana"
2) "140"
3) "apple"
4) "150"
WindowsServer:0>

Tips:zinterstore首先取交集,然后把分数累加

并集示例:

WindowsServer:0>zunionstore zunion_temp 2 fruits1 fruits2
"4"
WindowsServer:0>zrange zunion_temp 0 -1 withscores
1) "tomato"
2) "60"
3) "pear"
4) "80"
5) "banana"
6) "140"
7) "apple"
8) "150"
WindowsServer:0>

Tips:zunionstore首先取交集,然后把分数累加

2.6 通用指令

2.6.1 key的类型

redis的key 值是二进制安全的,这意味着可以用任何二进制序列作为key值,从形如”abc”的简单字符串到一个JPEG文件的内容都可以。Redis建议使用字符串做为key的类型

注意:空字符串也是有效key值。

  • key取值规范
    • (1)键值不需要太长,消耗内存,在数据中查找这类键值的计算成本较高
    • (2)键值不宜过短,可读性较差,通常建议见名知意。
  • 取值举例:

将如下数据库表中的数据,转换为redis的key-value存储

id username password email
1 lisi 111111 lisi@163.com

建议格式:

obj名:id:id值
127.0.0.1:6379> set user:id:1:username lisi 
OK 
127.0.0.1:6379> set user:id:1:password 111111
OK 
127.0.0.1:6379> set user:id:1:email lisi@163.com 
OK
 
127.0.0.1:6379> keys user:id:1* 					# 查找有几个属性
1) "user:id:1:password" 
2) "user:id:1:username" 
3) "user:id:1:email" 
127.0.0.1:6379>

2.6.2 key基本操作

  • 删除key
del key
  • 判断key是否存在
exists key
  • 获取key的类型
type key
  • key改名
rename key newkey

2.6.3 控制key的时效性

  • 为指定key设置有效期
expire key seconds
pexpire key milliseconds
  • 获取key的有效时间
ttl key			# 返回key的有效时间,单位秒
pttl key		# 返回key的有效时间,单位毫秒

如果key没有设置有效期(永久存在),返回-1

如果key不存在返回-2

如果key存在返回key的有效时间

  • 切换key从时效性转换为永久性
persist key

2.6.4 key的查询操作

  • 查询key
keys pattern

查询匹配规则:

  • *:匹配任意数量的任意符号
  • ?:匹配任意一个符号
  • []:匹配一个指定符号
keys * 查询所有
keys java* 查询所有以java开头
keys *java 查询所有以java结尾
keys ??java 查询所有前面两个字符任意,后面以java结尾
keys user:? 查询所有以user:开头,最后一个字符任意
keys j[av]a 查询所有以j开头,以a结尾,中间包含一个字母,a或v

2.6.5 key排序

  • 对所有key排序:只能对集合进行排序(listsortsorted-set
SORT key [BY pattern] [LIMIT offset count] [ASC|DESC] [ALPHA] [STORE destination]
  • list排序示例:
WindowsServer:0>lpush list 22 33 11 44 88 77 55
"7"
WindowsServer:0>sort list 
1) "11"
2) "22"
3) "33"
4) "44"
5) "55"
6) "77"
7) "88"
WindowsServer:0>sort list desc
1) "88"
2) "77"
3) "55"
4) "44"
5) "33"
6) "22"
7) "11"
WindowsServer:0>
  • set排序示例:
WindowsServer:0>sadd set 22 33 11 44 88 77 55
"7"
WindowsServer:0>sort set 
1) "11"
2) "22"
3) "33"
4) "44"
5) "55"
6) "77"
7) "88"
WindowsServer:0>sort set desc
1) "88"
2) "77"
3) "55"
4) "44"
5) "33"
6) "22"
7) "11"
WindowsServer:0>
  • zset排序示例:
WindowsServer:0>sort zset_key alpha			# zset排序需要加上alpha参数
1) "apple"
2) "pear"
3) "tomato"
WindowsServer:0>sort zset_key alpha desc
1) "tomato"
2) "pear"
3) "apple"
WindowsServer:0>

2.6.6 数据库通用操作

在一个redis中会有16个数据库,分别为db0、db1、db2.....

  • 切换数据库
select num

select 0 		# 切换到0数据库
select 1		# 切换到1数据库
  • 数据清除
dbsize			# 查看当前数据库共有多少个key
flushdb			# 清除当前数据库的所有数据
flushall		# 清除所有数据库的所有数据

三、Jedis连接Redis服务器

3.1 Jedis简介

Redis不仅是使用命令来操作,现在基本上主流的语言都有客户端支持,比如java、C、C#、C++、php、Node.js、Go等。在官方网站里列一些Java的客户端,有Jedis、Redisson、Jredis、JDBC-Redis、等其中官方推荐使用Jedis和Redisson。 在企业中用的最多的就是Jedis。Jedis提供了完整Redis命令,而Redisson有更多分布式的容器实现。

3.2 Jedis的使用

3.2.1 引入Maven依赖

<!--连接驱动-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

3.2.2 Jedis连接redis服务端:

@Test
public void test1() {

    // 创建一个Redis连接
    Jedis jedis = new Jedis("localhost");

    System.out.println("连接redis服务端成功!");

    //测试redis服务器是否正在运行
    System.out.println("redis服务器正在运行吗?" + jedis.ping());
    
    // 获取redis服务的配置信息
    System.out.println("redis服务器信息?\n" + jedis.info());
}

注意:

1.防火墙需要放行6379默认端口

2.使用jedis连接redis可能会出现的问题及解决方案

3.2.3 Jedis操作String数据类型

@Test
public void test2() {           // String 操作
    // 创建一个Redis连接
    Jedis jedis = new Jedis("localhost");

    String result = jedis.set("name", "hangman");

    System.out.println(result);

    String name = jedis.get("name");
    System.out.println(name);
}

3.2.3 Jedis操作Hash数据类型

@Test
public void test3() {           // Hash操作
    // 创建一个Redis连接
    Jedis jedis = new Jedis("localhost");

    jedis.hset("user","username","root");
    jedis.hset("user","password","admin");

    String username = jedis.hget("user", "username");
    String password = jedis.hget("user", "username");

    System.out.println(username);
    System.out.println(password);

    // 释放资源
    jedis.close();
}

3.2.4 Jedis操作List数据类型

@Test
public void test4() {           // List操作
    // 创建一个Redis连接
    Jedis jedis = new Jedis("localhost");

    Long result = jedis.lpush("fruits", "apple", "pear", "banana", "tomato");
    System.out.println(result);

    List<String> fruits = jedis.lrange("fruits", 0, -1);
    System.out.println(fruits);
}

3.2.5 Set测试

  • set基本操作
@Test
public void test5() {           // Set操作
    // 创建一个Redis连接
    Jedis jedis = new Jedis("localhost");

    Long result = jedis.sadd("cities", "lanzhou", "fuzhou", "guangzhou", "hangzhou", "zhengzhou");

    System.out.println(result);

    Set<String> cities = jedis.smembers("cities");
    System.out.println(cities);
}
  • 取交集、差集、并集:
@Test
public void test6() {           // Set操作求交集、差集、并集
    // 创建一个Redis连接
    Jedis jedis = new Jedis("localhost");

    jedis.sadd("cities1", "lanzhou", "fuzhou", "guangzhou", "hangzhou", "zhengzhou");
    jedis.sadd("cities2", "meizhou", "guangzhou", "quanzhou", "fuzhou", "ganzhou");

    // [guangzhou, fuzhou]
    Set<String> sinter = jedis.sinter("cities1", "cities2");
    System.out.println(sinter);

    // [zhengzhou, hangzhou, lanzhou]
    Set<String> sdiff = jedis.sdiff("cities1", "cities2");
    System.out.println(sdiff);

    // [fuzhou, guangzhou, hangzhou, lanzhou, meizhou, ganzhou, quanzhou, zhengzhou]
    Set<String> sunion = jedis.sunion("cities1", "cities2");
    System.out.println(sunion);
}

3.2.6 Zset测试

@Test
public void test7() {           // zset操作
    // 创建一个Redis连接
    Jedis jedis = new Jedis("localhost");

    jedis.zadd("students",100,"xiaohui");
    jedis.zadd("students",80,"xiaolan");
    jedis.zadd("students",99,"xiaojun");

    // 获取所有的key
    Set<String> students = jedis.zrange("students", 0, -1);
    System.out.println(students);

    System.out.println();
    Set<Tuple> studentsTuple = jedis.zrangeWithScores("students", 0, -1);

    for (Tuple tuple : studentsTuple) {
        System.out.println("key: "+tuple.getElement());
        System.out.println("score: "+tuple.getScore());
    }

    // 释放资源
    jedis.close();
}

3.3 Jedis 连接池

package com.dfbz.demo01;

import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Demo02_Pool {


    @Test
    public void test1() {
        // 创建Jedis连接池配置对象
        JedisPoolConfig config = new JedisPoolConfig();

        // 最大连接数
        config.setMaxTotal(30);
        // 最大空闲连接数
        config.setMaxIdle(10);
        // 最小空闲连接数
        config.setMinIdle(5);
        // 最长等待毫秒数
        config.setMaxWaitMillis(3000);

        // 创建一个Jedis连接池
        JedisPool jedisPool = new JedisPool(config, "127.0.0.1", 6379);

        for (int i = 0; i < 31; i++) {
            Jedis jedis = jedisPool.getResource();
            if (i == 20) {
                jedis.close();          // 将连接归还到连接池
            }
            System.out.println(jedis);
        }

        jedisPool.close();          // 释放资源
    }
}
posted @ 2023-11-06 15:30  绿水长流*z  阅读(69)  评论(0)    收藏  举报