Redis
# 前言
# Nosql基础概念
NoSQL最常见的解释是“non-relational”, “Not Only SQL”也被很多人接受。NoSQL仅仅是一个概念 (opens new window),泛指非关系型的数据库,区别于关系数据库 (opens new window),它们不保证关系数据的ACID特性。NoSQL是一项全新的数据库革命性运动,其拥护者们提倡运用非关系型的数据存储 (opens new window),相对于铺天盖地的关系型数据库 (opens new window)运用,这一概念无疑是一种全新的思维的注入。
# Nosql分类
键值(Key-Value)存储数据库
这一类数据库主要会使用到一个哈希表 (opens new window),这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果数据库管理员 (opens new window)(DBA (opens new window))只对部分值进行查询或更新的时候,Key/value就显得效率低下了。举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB。
列存储数据库
这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak。
文档型数据库
文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可以看作是键值数据库的升级版,允许之间嵌套键值,在处理网页等复杂数据时,文档型数据库比传统键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。
图形(Graph)数据库
图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。如:Neo4J, InfoGrid, Infinite Graph。
# Redis介绍
# 基本概念
Redis是使用c语言开发的一个高性能键值数据库。Redis可以通过一些键值类型来存储数据。 键值类型:
String字符类型 map散列类型 list列表类型 set集合类型 sortedset有序集合类型
# 应用场景
缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用) 分布式集群架构中的session分离。 聊天室的在线好友列表。 任务队列。(秒杀、抢购、12306等等) 应用排行榜。 网站访问统计。 数据过期处理(可以精确到毫秒)
# Redis安装
Windos和Linux上的安装参考菜鸟教程 (opens new window)
本文档在Linux上使用Docker安装Redis进行相关的学习。
# Docker安装
Docker相关的知识参考Dokcer从入门到实践 (opens new window)
- 安装Dokcer
yum install -y docker
- 查看Dokcer是否安装成功
yum list installed |grep docker
- 启动Dokcer服务
systemctl start docker.service
- 查看Docker是否启动成功
systemctl status docker
- 设置Dokcer开机自启动
systemctl enable docker.service
# Dokcer拉取Redis
拉取镜像到Linux(Dokcer中Linux镜像地址:https://hub.docker.com/_/redis/?tab=description)
docker pull redis
查看镜像是否拉取成功
docker images
启动Redis
docker run --restart=always -d -p 6379:6379 --name redis 40c68ed3a4d2
查看容器
dokcer ps
进入容器测试Redis
# Redis客户端
# 自带客户端
启动
./redis-cli -h 127.0.0.1 -p 6379
-h 指定访问 redis 服务器的 ip 地址 -p 指定访问的 redis 服务器的 port 端口 还可以写成 ./redis-cli 使用默认配置,默认ip 127.0.0.1,默认端口 6379关闭 ctrl + c 127.0.0.1:6379>quit
# 图形界面客户端
这里推荐AnotherRedisDesktopManager (opens new window)
# 数据类型
# String 类型
# 基本操作
赋值 set key value
> set test 123456
取值 get key
> get test
123456
取值并赋值 getset key value
> getset test 123
123456
> get test
123
设置获取多个键值 mset key value [key value...] mget key [key...]
> mset name1 wxx1 name2 wxx2 name3 wxx3
OK
> mget name1 name2
wxx1
wxx2
删除 del key
> del test
0
数值增减
递增 incr key
> set num 10 OK > incr num 11 > incr num 12
指定递增的数量 incrby key increment
> incrby num 2 14 > incrby num 5 19
递减 decr key
> decr num 18 > decr num 17
指定递减的数量 decrby key decrement
> decrby num 2 15 > decrby num 5 10
# 字符串相关操作
末尾追加 append,返回是追加字符串的总长度
> set str hello OK > get str hello > append str world 10 > get str helloworld
长度 strlen
> strlen str 10
# 应用
自增主键 商品编号、订单号采用 string 的递增数字特性生成
# Hash 散列类型
在开发中,当我们需要存储的是一个对象的时候,比如我要存储User这个对象,然后这个对象里面有对象的属性,这时候就需要使用到Hash
我们的User就是一个Key,然后User的所有字段是一个value,在这个value中又有字段这个key,字段的key对应的value是字段值。相当于一个Map,然后第一个Map的value又是一个Map。
# HSET 命令
赋值 HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0。
一次设置一个字段 hset key field value
> hset user name wxx 1
一次设置多个字段 hmset key field value [field value...]
> hmset user age 18 sex male OK
当字段不存在时赋值 hsetnx key field value
> hsetnx user area chengdu 1 > hget user area chengdu
# HGET 命令
一次获取一个字段 hget key field
> hget user name wxx
一次获取多个字段 hmget key field [field...]
> hmget user name sex wxx male
一次获取所有字段,相当于获取这个对象 hgetall key
> hgetall user name wxx age 18 sex male area chengdu
# HDEL 命令
删除某个或多个字段字段 hdel key field [field...]
> hdel user name 1 > hgetall user age 18 sex male area chengdu > hdel user age sex 2 > hgetall user area chengdu
# 其他 命令
增加数字 hincrby key field increment
> hset user age 18 1 > hget user age 18 > hincrby user age 2 20
判断字段是存在 hexists key field
> hexists user age 1
只获取字段名或字段值 hkeys key
> hkeys user area age
获取字段数量 hlen key
> hlen user 1
# 应用
存储一些权限信息,或者一些通用的字典信息等。
# List 类型
Redis的list是采用来链表来存储的,所以对于redis的list数据类型的操作,是操作list的两端数据来操作的。
# LPUSH 命令
右边插入 lpush key value [value...]
> lpush list 1 2 3
3
# RPUSH 命令
左边插入 rpush key value [value...]
> rpush list 4 5 6
6
# LRANGE 命令
查看列表 LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。lrange key start stop
> lrange list 0 2
3
2
1
> lrange list 2 5
1
4
5
6
> lrange list 3 5
4
5
6
# LPOP 命令
先弹出元素将其删除,然后返回元素值
lpop key
> lpop list
3
# RPOP 命令
rpop key
> rpop list
6
# LLEN 命令
获取列表中元素的个数 llen key
> llen list
3
# LREM 命令
删除列表中指定的值 LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。lrem key count value
根据count值的不同,该命令的执行方式会有所不同:
- 当count>0时, LREM会从列表左边开始删除。
- 当count<0时, LREM会从列表后边开始删除。
- 当count=0时, LREM删除所有值为value的元素。
# LINDEX 命令
获得指定索引的元素值 lindex key index
> lindex list 0
3
# LSET 命令
修改指定索引的元素值 lset key index value
> lset list 0 50
OK
> lindex list 0
50
# LTRIM 命令
保留列表指定片段 ltrim key start stop
> rpush list 99 100 99 100
6
> lrange list 0 -1
50
2
99
100
99
100
> ltrim list 0 -1
OK
> lrange list 0 -1
50
2
99
100
99
100
> ltrim list 0 2
OK
> lrange list 0 -1
50
2
99
# LINSERT 命令
向列表中插入元素 该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。
linsert key before | after pivot value
> linsert list before 66 55
3
> lrange list 0 -1
50
55
66
> linsert list after 66 77
4
> lrange list 0 -1
50
55
66
77
# RPOPLPUSH 命令
将元素从一个列表转移到另一个列表 rpoplpush source destination
> rpoplpush list newlist
77
> lrange newlist 0 -1
77
> lrange list 0 -1
50
55
66
# 应用
用户所添加的商品转为json存入list中,用户在查看购物车列表的时候,从redis取出json数据展示出来。
# Set 类型
上面的List类型是有序的、可重复的,但是Set类型是无序的,不可重复的。
# SADD 命令
添加一个元素,sadd key member [member...]
> sadd set a b c
3
> sadd set a
0
# SREM 命令
删除一个元素, srem key member [member...]
> srem set a
1
# SMEMBERS 命令
获取所有元素,smembers key
> smembers set
c
b
# SISMEMBER 命令
判断元素是否在集合中 ,sismember key member
> sismember set a
0
> sismember set c
1
# 运算命令
# 集合差
sdiff key [key...]
> sadd setA 1 2 3
3
> sadd setB 2 3 4
3
> sdiff setA setB
1
> sdiff setB setA
4
# 集合交集
sinter key [key...]
> sinter setA setB
2
3
# 集合并集
sunion key [key...]
> sunion setA setB
1
2
3
4
# 集合中的个数
scard key
> smembers setA
1
2
3
> scard setA
3
# 集合中弹出元素
set由于是无序的,所以会随机弹出一个元素。
> spop setA
3
> smembers setA
1
2
# Sortedset 类型
Sortedset 又叫 zset Sortedset 是有序集合,可排序的,但是唯一。 Sortedset 和 set 的不同之处,会给 set 中元素添加一个分数,然后通过这个分数进行排序。
# ZADD 命令
向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。zadd key score member [score member...]
> zadd sortset 10 wxx1 20 wxx2 30 wxx
3
# ZSCORE 命令
获取元素分数 zscore key member
> zscore sortset wxx1
10
# ZREM 命令
删除一个元素 zrem key member [member...]
> zrange sortset 0 -1
wxx2
wxx
wxx01
wxx1
> zrem sortset wxx1
1
> zrange sortset 0 -1
wxx2
wxx
wxx01
# ZRANGE 命令
按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素
zrange key start stop [withscores]
> zrange sortset 0 1
wxx2
wxx
> zrange sortset 0 2
wxx2
wxx
wxx01
# ZREVRANGE 命令
按照元素分数从大到小的顺序返回索引从start到stop之间的所有元素
zrevrange key start stop [withscores]
> zrevrange sortset 0 1
wxx01
wxx
如果需要获取元素的分数,可以加入withsocres参数
> zrange sortset 0 -1 withscores
wxx2
20
wxx
30
wxx01
90
ZRANK
zrank key member
> zrange sortset 0 -1
wxx2
wxx
wxx01
> zrank sortset wxx2
0
ZREVRANK
zrevrank key member
> zrevrank sortset wxx2
2
# ZRANGEBYSCORE
获得指定分数范围的元素
> zrange sortset 0 -1 withscores
wxx2
20
wxx
30
wxx01
90
> zrangebyscore sortset 90 100
wxx01
# ZINCRBY
增加某个元素的分数 zincrby key increment member
zincrby key increment member
# ZCARD
获取集合中元素的数量
> zrange sortset 0 -1
wxx
wxx2
wxx01
> zcard sortset
3
# ZCOUNT
获取指定分数范围内的元素个数
> zrange sortset 0 -1 withscores
wxx
30
wxx2
30
wxx01
90
> zcount sortset 40 90
1
# ZREMRANGEBYRANK
按照排名范围删除元素
> zremrangebyrank sortset 1 -1
2
> zrange sortset 0 -1
wxx
# ZREMRANGEBYSCORE
按照分数范围删除元素
> zrange sortset 0 -1 withscores
wxx
30
C
56
B
88
A
99
> zremrangebyscore sortset 30 56
2
> zrange sortset 0 -1 withscores
B
88
A
99
# Keys命令
# 常用命令
# keys
返回满足给定pattern 的所有key
> keys set
set
> keys set*
setA
setB
set
# exists
确认一个keys是否存在
> exists set
1
> exists 444
0
# del
删除一个key
> del set
1
> exists set
0
# rename
重命名一个key
> rename setA setNew
OK
> exists setA
0
> exists setNew
1
# type
判断key的类型
> type setB
set
> type sortset
zset
# 生存时间
Redis在实际使用过程中更多的用作缓存,然而缓存的数据一般都是需要设置生存时间的,即:到期后数据销毁。
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以毫秒为单位,返回 key 的剩余生存时间。
EXPIRE key seconds | 设置key的生存时间(单位:秒)key在多少秒后会自动删除 |
TTL key | 查看key剩余的生存时间 |
PERSIST key | 清除生存时间 |
PEXPIRE key milliseconds | 生存时间设置单位为:毫秒 |
> set test 123456
OK
> type test
string
> get test
123456
> ttl test
-1
> expire test 5
1
> ttl test
0
> ttl test
-2
> get test
null
# 参考
https://juejin.cn/post/6844903639765483533#heading-51