配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#redis.conf

设置显示行号   
:set nu

搜索       /daemonize
把daemonize no 的no改为yes
#(该配置为是否让redis作为服务(守护进程)在后台启动)


搜索       /protected-mode
把protected-mode yes 改为no
#(该配置为resis的安全模式,当他开启就会禁止别人访问redis,如操作redis的工具)

搜索       /bind 127.0.0.1 -::1
注释掉bind 127.0.0.1 -::1
#(该配置生效时表示只有本机能访问redis,这显然是不行的,注释掉它)


搜索requirepass foobared
把改行的注释取消掉 并把 foobared 改成自己的密码
(该配置为设置自己的redis登录密码)

搜索      /port 6379
把端口号修改成自己需要的端口。

服务启动/结束

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#使用我们修改好的 redis.conf 配置文件启动服务!
redis-server /opt/redis-7.0.0/redis/redis.conf

#查看redis服务是否启动 
ps -aux | grep redis | grep -v grep

#使用我们修改过的 密码 以及 端口号 登录客户端!
redis-cli -a 你的密码 -p 你的端口

#在Redis命令行中:输入shutdown退出(quit退出服务)

#在Redis命令行外:
redis-cli -a 你的密码 -p 你的端口(可填多个端口) shutdown

常用命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
help @?
# 查询帮助,比较有用

set k v
#设置一个String类型的数据k 值为v

get k      
#获取k?的值

keys *
#查询所有key

exists k
#k是否存在,返回1表示存在

type k
#查询数据类型

del k
#删除指定key

unlink k
#异步删除,对于大数据的删除,使用异步防止阻塞

ttl  k
#数据是否过期,返回-1表示永不过期,-2表示已过期。数据在默认情况下永不过期
             
expire k S
#设置k在s秒后过期(过期会删除该值)

move k index   
#将k移动到下标为index的数据库中

select  index   
#切换到下标为index的数据库

#(redis中我们默认处于0号数据库)

dbsize          
#统计数据库中key的数量

flushdb         
#清空当前数据库(谨慎使用!)

flushall        
#清空所有数据库(谨慎使用!)

十大数据类型

String(字符串)

  • String是redis中最基本的数据类型,一个key对应1个value
  • redis中的String是二进制安全的(支持序列化),这意味着我们可以将二进制存储的文件存入其中,比如:一张图片。
  • redis中单个String的最大容量为521M

基础命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
set命令中的可选参数分别有
get EX PX EXAT PXNX NX XX KEEPTTL 

GET用法   
set k1 jack GET  
#它会把k1赋值为jack,但同时返回k1之前的值

EX用法
set k1 jack EX 10  
#设置k1值为jack,但在10秒后过期(expire)

PX用法
set k1 jack PX 100  
#设置k1值为jack,但在100毫秒后过期

EXAT用法
set k1 jack EXAT 1685775704 
#设置k1值为jack,但在指定的秒级unix时间戳后过期

set K1 JACK PXAT 1685775857409
#设置k1值为jack,但在指定的毫秒级unix时间戳后过期

NX用法
set k1 jack NX  
#当k1不存在时设置k1的值为jack

XX用法
set k1 tom XX   
#当k1存在时才将k1的值设为tom

KEEPTTL用法
set k1 jack KEEPTTL
#当我们在设置给key赋值时偶然或遇到这样的业务需求,只改变key的值,但不要改变之前设置的过期时间。
#这时我们就需要用到KEEPTTL,要知道普通的set赋值会改变value的过期时间(默认为-1:即永不过期)

mset k1 v1 k2 v2 k3 v3   
#设置多个值(m multi多个)
#注意 mset k1 v1 k2 v2 k3 v3 NX 当其中一个不满足条件则全部失败

mget k1 k2 k3 k4   
#获取多个值

getrange k1 1 2    
#截取k1,从下标1-下标2

getrange k1 0 -1   
#获取全长

setrange k1 1 omomom    
#定位替换,从下标1开始替换字符串

INCR k2      
#递增k2(k2必须为数字!)

DECR K2      
#递减k2(k2必须为数字!)

INCRBY k2 2   
#每次递增步长为2

DECRBY k2     
#每次递减步长为2

strlen  k1    
#获取k1的长度

append  k1    
#往k1尾部插入字符

getset k1 v1  
#与set k1 v1 get一样,它会把k1赋值为v1,但同时返回k1之前的值

分布式锁

1
2
3
4
5
setnx k1 jack
#当k1不存在设置值为jack

setex k1 jack   
#当k1存在设置值为jack

set k1 jack nx与setnx k1 jack区别

set k1 locked nx (查看与上锁)
服务1 查看是否上锁(同时其他的服务也在查看)
服务1 上锁过程中, 服务2 认为没有上锁,发生线程安全问题

setnx (单个原子操作)
服务1 开始查看(其他服务等待)
(查看锁与上锁属于不可分割的原子操作,其他服务只能等待)

list(列表)

  • redis中的list指的是简单的字符串列表
  • 你可以插入一个字符串到头部或者尾部,数据结构其实就是双向链表
  • 它最多包含 2 ^ 32 - 1个元素,超过40亿个

基础命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
lpush list1 1 2 3 4
#从左侧 依次 将12345插入到list1中

lrange list1 0 -1
#从左侧开始遍历整个list1
#5 4 3 2 1

rpush list2 1 2 3 4 5 
#从右侧 依次 将12345插入到list1中

lrange list2 0 5
#从左侧开始遍历list2 从0-5
#1 2 3 4 5

lpop list1    
#从左侧弹出一个元素

rpop list1    
#从右侧弹出一个元素

lindex list1 n    
#找出从左侧数下标为n的元素


lrem list1 n tom   
#从左侧开始数,删除n个tom


ltrem list1  n  m  
#裁剪list1,只保留从下标n到下标m(会改变原list!)

rpoplpush  list1 list2  
#把list1元素尾部取出,插入list2头部(它是原子操作)

lset list1  n tom  把list1中下标为n的元素替换为tom

linsert list1 before/after tom jack
#在list1中,给元素tom的前面或者后面添加一个jack
#注意:list中的元素是可以重复的!当有多个tom时,它只会在第一个tom的前面添加,而不是在每个tom前面都添加

Hash (哈希表)

  • 以一个filed(字段 String) 一个value(值)来存储数据的映射表。与Java中的hashmap数据结构极为相似:
  • map< String,map< String,object > >
  • 单个hash最多包含 2 ^ 32 - 1个键值对,超过40亿个键值对

基础命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
hset user name tom age 12 hobby sing
#设置一个key为 user 的hash 它的值是一个个键值对
#分别是 name tom ,age 12 ,hobby sing

hget user name   
#获取hash表user的name属性

hgetall user   
#获取hash表user的n所有属性

hlen user    
#获取hash表user的键值对个数

hexists user name    
#hash表user有没有name属性

hkeys user     
#查询user中所有键值对中的key

hvals user     
#查询user中所有键值对中的value

hincreby user age n      
#给user的年龄字段增加n
#(注意,他没有hdecrby递减 但是我们可以增加 -1,相当于递减了)

hincrbyfloat user age 0.5    
#float类型增加

hsetnx user hobby coding
#当的hobby字段不存在时赋值为coding (原子操作)

set(集合)

  • redis中的set是存储String的无序集合,要求存储的String数据数据唯一无重复
  • 底层其实由hash来实现的,集合对象的编码类型可以是inset或者hashtable
  • 它的查询复杂度为 O1,做法与java一样,value全部置空,比对key就完了
  • 单个set最多包含 2 ^ 32 - 1个成员,超过40亿个成员

基础命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
sadd set1 1 2 3 4 5 5 5 5
#添加将1 2 3 4 5 添加到 set1中,set会自动去重

smember set1  
#遍历set1所有 成员(member)

sismember set1 x  
#x是否是set1的成员

srem set1 x   
#删除set1中的x元素

scard set1   
#获取set1的长度

srandmember set1  
#随机显示一个set1中的元素

spop set1 n  
#随机弹出(删除)n个set1中的元素

smove set1 set2 x  
#将x从set1中移动到set2中

sdiff set1 set2   
#获得set1中有而set2中没有的元素,差集

union set1 set2   
#获得set1与set2合并后的set,并集

sinter set1 set2  
获得set1与set2中共有的数据交集

sintercard 2 set1 set2  
#获得set1与set2这2个set交集的长度
#注意,必须指定要获得交集长度的set个数 (2) 

zset(sorted set)

  • 它是一个有序的无重复set 可以有序的存储String,它通过给每一个value指定一个double类型的score分数来设定value该放置的位置
  • zset的分数可以重复,但成员唯一
  • 查询,插入,删除复杂度都是O1
  • 可存储 2 ^ 32 - 1个成员

基础命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
zadd  zset1  10 tom  20 jack  30 lisa  40 monika
#给zset1中添加 tom jack lisa monika,他们关联的score分别是10 20 30 40

zrange zset1 0 -1 withscores    
#遍历zset1  withscores 带上score

zrevrange zset1 0 -1   
#反向遍历zset1

zrangebyscore zset1 0 100  
#获取zset1的score,不能填0 -1,要填分数的范围,0 100的意思是获取的score要大于等于0 小于等于100的

zrangebyscore zset1 (0 100  
#括号表示不包含0

zrangebyscore zset1 0 100 limt 0 1 
#limt 0 1 表示只要两个数,类似于分页

zrem zset1 tom  
#删除tom 它无法通过分数获取指定的元素,score只用来排序

zcard zset1   
#获取zset1的长度

zincrby zset1 3 tom  
#tom加3分

zcount zset1 0 20   
#统计从0分 到 20分之间有几个元素

zmpop 2 zset1 zset2 min/max count 1
#对zset1和zset2进行元素删除 最小或最大 删除数量为1(他会先删除zset1),删除完后删除
#zset2,如果指定的count数大于zset的总长度,则删除当前zset的全部,不会影响下一个zset

zrank zset1 tom   
#获得zset1中tom的下标

zrevrank zset1 tom  
#获得逆序中tom的下标

GEO (地理位置信息)

  • 用来存储经纬度,可以对存储的经纬信息进行操作,底层还是zset
  • 存储位置信息
  • 删除位置信息
  • 计算两个位置信息之间的距离

基础命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
geoadd city 116.403968 39.915094 "天安门" 116.403414 39.924091 "故宫" 116.746579 40.482509 "长城"
#将经纬度与名称存入city中

zrange city 0 -1  
#遍历city (zset数据类型不能使用参数 0 -1直接获取全部,而它可以)
#出现乱码需要退出登录,重新登录时在登录指令后添加 --raw ,此时zrange指令不再乱码。

geopos city 天安门    
#返回定位点的坐标

geohash city 天安门   
#//wx4g0f6f300
#工作中面对大量的定位置,一个经度,一个维度一般使用geohash
#将定位信息转换成base32编码使用。(这并不影响存入的数据本身,只是获取数据的编码)

geodist city 天安门 故宫 m / km / ft(英尺) / mi(英里)
#获取在city中天门到故宫两地之间的距离,不输入单位则默认是米

georadius city 经度 纬度 100 km withdist withcoord withhash count 10 desc
#withdist 带上距离 
#withcoord 带上经纬度坐标 
#withhash 带上base32编码
#count 数量
#desc 倒序
#经纬度指定点为圆心,半径100km以内的最多10个坐标,并带上坐标的经纬度,跟指定坐标之间的距离,带上编码,然后倒序排列。

georadiusbymamber city 天安门 100 km
#以天安门为圆心半径一百千米的地点名称

HyperLogLog (基数统计)

  • 基数就是指不重复的数据,比如人口基数,指的就是每个单独存在的个体
  • HyperLogLog是用来做基数统计的算法,它的优点在于统计大数量的基数时,运算速度会非常快。
  • 对于2 ^ 64 -1 个数据的统计,只需要占用12k的内存,要知道一般的集合,它存储的数据量越大,进行基数统计时所需要占用的内存就越大。
  • 它不像常用的数据类型一样,存储基数本身,也无法返回指定的基数。

基础命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
pfadd date01 tom jack jack lisa lisa lisa
#定义了一个名为date01的HyperLogLog
#在这一天tom访问网站一次,jack两次,lisa三次
#注意命名以非数字开头

pfcount  date01
#统计访问人数,结果为3

pfadd date02 tom jack jack lisa lisa lisa monika
#我们统计2号的访问用户基数

pfmerge result date01 date02
#2号相比1号访问用户增加了monika,上述命令统计两天访问的用户并通过result的新HyperLogLog中

bitmap(位图)

  • 是用来存储二进制位的bit数组,当我们只需要记录简单的Y/N状态时,他就派上大用场了,比如,打卡上班,统计调研分析。

基础命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
setbit k1 1 1     
#将k1 下标为1的位置设为1

get k1   
#我们使用获取字符串的方式来获取k1,返回的是它所指定的ascii码所对应的值
#如1 表示的就是2进制 01000000 (众所周知二进制0开头) 对应的就是字符 @ 

getbit k1 n  
#我们通过getbit来获取下标n上面的数字 下标必须指定

strleng k1   
#我们获取的是该bitmap占用的字节,8位一字节。比如0100 0000 1所占用的就是2字节

bitcount k1   
#获取k1中一共有多少个1(用于统计上班签到)

bitfield(位域)

  • 分段操作的bitmap

Stream redis流

  • redis版的消息队列

数据持久化

Redis的持久化在配置文件redis.conf中记录

RDB(redis database)

Redis按照一定的时间间隔(触发条件)执行对数据进行备份。称之为时间点快照。文件名为dump.rdb

指令

SAVE指令 实际生产中禁止使用该指令,因为该指令会阻塞Redis!致使Redis不服务而去进行持久化操作!

BGSAVE指令 生产中我们会使用该指令立即持久化操作,它会另起一个Redis的子线程去异步的执行持久化操作,不会影响Redis正常提供服务!

LASTSAVE指令 该指令可以查看最后一次备份的执行时间

配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
修改配置文件 vim /opt/redis-7.0.0/redis.conf

更改RDB备份存储位置
搜索 dir ./  按n切换下一个
将 ./ 换成你想保存的目录

更改RDB备份文件名
搜索 dbfilename dump.rdb  
把 dump.rdb 改成  redis端口号 + dump.rdb

更改RDB备份频率
搜索 save 3600 1 300 100 60 10000
在3600秒(1小时)内有1个键发生了改变
在300秒(5分钟)内10个键发生改变
在60秒内10000个键发生改变
另起一行写入规则
如 save 5 1

禁用RDB备份
将配置文件redis.conf中的save 改成 save ""

注意,配置修改后重启redis服务才会生效!
1 shutdown结束服务
2 redis-server +配置文件路径   重启Redis

AOF (append only file)

Redis记录数据库中所执行过的所有写操作,在服务器重启时重播这些操作重写数据库原始数据,命令的记录格式与 Redis 协议本身相同。

策略

always 在写命令执行后立即记录该条命令(频繁的磁盘IO会降低Redis性能)

everysec 默认 每秒写入1次,看似频率高,其实性能影响不大,最多丢失1秒内执行的写入,是最优选。

no 由操作系统控制的持久化。每条命令执行后,只是将命令存入AOF文件的内存缓冲区,由操作系统决定何时将缓冲区内容写入磁盘 。(宕机会丢数据!)

配置

1
2
3
4
5
6
7
8
9
修改配置文件 vim /opt/redis-7.0.0/redis.conf

开启AOF
搜索 appendonly no
将 no 改为yes

更改策略
搜索 appendfsync everysec
更改everysec

No persistence

不进行持久化操作

有时我们不需要Redis做备份,而是以更高的性能单纯的作为缓存数据库存在

即便禁用了aof与rdb,我们仍然可以使用bgrewirteaof或bgsave指令生成相应的备份

RDB+AOF

组合使用AOF和RDB进行持久化,当Redis同时开启了RDB与AOF,则Redis在开启服务时会优先选择AOF来恢复数据, 如果不存在,则会去寻找RDB文件恢复,如果都没有则不恢复直接启动

配置

1
aof-use-rdb-preamble yes 开启混合模式!