Redis配置讲解及实战

前言

Redis是一个开源的内存k-v数据库,同时也可用作缓存,消息队列。支持多种数据类型,如字符串,列表,字典,集合,有序集合。

演示环境

1$ uname -a 2Darwin 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64 3$ redis-server -v 4Redis server v=5.0.5 sha=00000000:0 malloc=libc bits=64 build=31cd6e21ec924b46

安装

brew install redis

配置

Redis 默认用过的配置文件路径位于/usr/local/etc/redis.conf,下面将通过修改该配置文件影响Redis的行为。

Redis 默认是运行在前台,当终端退出时Redis也会退出,所以首先的任务是通过修改配置文件让Redis运行在后台:

daemonize yes

然后通过下面的命令启动Redis:

redis-server /usr/local/etc/redis.conf

Redis启动后可以看到redis-server进程监听在127.0.0.1:6379,可以通过下面的配置项修改:

1bind 127.0.0.1 ::1 2port 6379

通过Redis客户端redis-cli连接Redis服务端redis-server:

1$ redis-cli 2127.0.0.1:6379> 3127.0.0.1:6379> set hello world # 字符串操作 4OK 5127.0.0.1:6379> keys * # 列举所有的key 61) "x1" 72) "x2" 83) "hello" 9127.0.0.1:6379> hset myhash 1 www #字典(哈希表)操作 10(integer) 1 11127.0.0.1:6379> hset myhash 2 yyy 12(integer) 1 13127.0.0.1:6379> 14127.0.0.1:6379> 15127.0.0.1:6379> hgetall myhash # 获取字典myhash所有的key-value 161) "1" 172) "www" 183) "2" 194) "yyy" 20127.0.0.1:6379> lpush mylist 1 # 列表操作,元素可以重复 21(integer) 1 22127.0.0.1:6379> lpush mylist 2 23(integer) 2 24127.0.0.1:6379> lpush mylist 3 25(integer) 3 26127.0.0.1:6379> lpush mylist 1 27(integer) 4 28127.0.0.1:6379> lrange mylist 0 -1 291) "1" 302) "3" 313) "2" 324) "1" 33127.0.0.1:6379> sadd myset 1 #集合操作,重复元素只保留一个 34(integer) 1 35127.0.0.1:6379> sadd myset 2 36(integer) 1 37127.0.0.1:6379> sadd myset 3 38(integer) 1 39127.0.0.1:6379> sadd myset 1 40(integer) 0 41127.0.0.1:6379> smembers myset 421) "1" 432) "2" 443) "3" 45127.0.0.1:6379> zadd mysortset 1 redis #有序集合操作,前面的score值,作为排序的依据 46(integer) 1 47127.0.0.1:6379> zadd mysortset 3 mysql 48(integer) 1 49127.0.0.1:6379> zadd mysortset 2 memcached 50(integer) 1 51127.0.0.1:6379> zrange mysortset 0 -1 withscores 521) "redis" 532) "1" 543) "memcached" 554) "2" 565) "mysql" 576) "3"

上面的操作演示了Redis字符串,列表,字典,集合,有序集合五种数据类型。redis-cli使用默认的配置连接redis-server,但是在生产环境中IP和Port:

1u$ redis-cli -h 2redis-cli 5.0.5 3 4Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]] 5 -h <hostname> Server hostname (default: 127.0.0.1). 6 -p <port> Server port (default: 6379).

配置redis-server鉴权

requirepass foobared

重启redis-server后,再次尝试用redis-cli连接操作:

1$ redis-cli 2127.0.0.1:6379> 3127.0.0.1:6379> keys * 4(error) NOAUTH Authentication required. 5127.0.0.1:6379>

这时就需要输入密码后才能接着操作:

1127.0.0.1:6379> auth foobared 2OK 3127.0.0.1:6379> keys * 41) "myset" 52) "mysortset" 63) "x1" 74) "mylist" 85) "myhash" 96) "x2" 107) "hello" 11127.0.0.1:6379>

持久化

Redis数据持久化策略有RDB快照方式和AOF(append only file)方式。

RDB 是Redis默认开启的持久化策略,相关的配置为:

1save 900 1 #900s有多于1个key发生变化则触发RDB持久化 2save 300 10 #300s有多于10个key发生变化则触发RDB持久化 3save 60 10000 #60s有多于10000个key发生变化则触发RDB持久化 4rdbcompression yes #数据压缩保存于rdb文件中 5rdbchecksum yes #开启rdb数据checksum确认功能 6dbfilename dump.rdb #rdb文件名称 7dir /usr/local/var/db/redis/ #rdb文件目录位置

Redis启动后会加载dump.rdb文件数据,如果dump.rdb 文件损坏或者不完整(有可能机器断电,最后一次的RDB数据持久化部分刷到dump.rdb文件),可以通过redis-check-rdb检测dump.rdb文件的可用性:

1$ redis-check-rdb dump.rdb 2[offset 0] Checking RDB file dump.rdb 3[offset 26] AUX FIELD redis-ver = '5.0.5' 4[offset 40] AUX FIELD redis-bits = '64' 5[offset 52] AUX FIELD ctime = '1561972490' 6[offset 67] AUX FIELD used-mem = '1006704' 7[offset 83] AUX FIELD aof-preamble = '0' 8[offset 85] Selecting DB ID 0 9[offset 266] Checksum OK 10[offset 266] \o/ RDB looks OK! \o/ 11[info] 7 keys read 12[info] 0 expires 13[info] 0 already expired

当dump.rdb 文件损坏且无法恢复时,需要删除dump.rdb文件,否则redis-server启动后会自动退出:

1$ echo " i am test hahhahha" > dump.rdb 2$ redis-server /usr/local/etc/redis.conf 323194:C 01 Jul 2019 17:44:34.757 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 423194:C 01 Jul 2019 17:44:34.757 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=23194, just started 523194:C 01 Jul 2019 17:44:34.757 # Configuration loaded 6$ ps -ef|grep redis 7 501 23264 46375 0 5:45下午 ttys002 0:00.00 grep redis

删除dump.rdb文件后,redis-server可以正常启动,但是之前的数据也没有了:

1$ rm dump.rdb 2$ redis-server /usr/local/etc/redis.conf 323498:C 01 Jul 2019 17:48:26.574 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 423498:C 01 Jul 2019 17:48:26.574 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=23498, just started 523498:C 01 Jul 2019 17:48:26.574 # Configuration loaded 6$ redis-cli 7127.0.0.1:6379> keys * 8(empty list or set) 9127.0.0.1:6379>

另外dump.rdb文件是二进制数据,用vim直接查看人眼无法看懂:

数据格式:

开头为固定的5个REDIS字符,表示为RDB文件。

db_version表示为redis的版本。

EOF表示正文内容结束。

checksum为8字节的无符号整数校验和。验证数据的完整性。

databases部分:

第一部分表示该什么是redis哪个DB的(0-15)。

第二部分db_number是具体的db需要,例如0。那么第一部分和第二部分加起来就是select 0。

第三部分key_value_pairs 表示的是具体键值对信息。

一个完整RDB文件内容示例:

RDB持久化关键点:

1.redis利用linux fork子进程后,进程拥有父进程内存快照的方式快速获取内存快照(copy on write)。

2.redis RDB持久化落盘操作发生在独立的子进程中,不影响主进程的其他请求。(对应于bgsave命令,如果是save命令还是主进程处理RDB)

RDB策略优点:

1.适合大规模的数据恢复,数据恢复快。

2.如果业务对数据完整性和一致性要求不高,RDB是很好的选择。

RDB策略缺点:

数据的完整性和一致性不高,异常情况下会丢失最后一次RDB备份前的数据。

AOF 策略

AOF的出现是为了和RDB互补,它采用日志的形式记录每个写操作的内容,将写指令从前到后执行一次以完成数据的恢复工作。

1appendonly yes 2appendfilename "appendonly.aof" 3# appendfsync always # 每发生一次写操作刷一次盘 4appendfsync everysec # 每秒定时刷盘 5# appendfsync no # 依靠系统自行刷盘

清空Redis然后重启redis-server:

1$ redis-cli 2127.0.0.1:6379> 3127.0.0.1:6379> 4127.0.0.1:6379> keys * 5(empty list or set) 6127.0.0.1:6379> 7127.0.0.1:6379> 8127.0.0.1:6379> set hello world 9OK 10 11$ cat appendonly.aof 12*2 #表示有两个参数 13$6 #该参数有6个字符 14SELECT #参数是select 15$1 #该参数有1个字符 160 #参数是0 17*3 #表示有3个参数 18$3 #该参数有3个字节 19set #参数是set 20$5 #该参数有5个字节 21hello # 参数是hello 22$5 #该参数有5个字节 23world # 参数是world

所以appendonly.aof 保存了命令还原为:

1select 0 2set hello world

其中select 0表示默认选择Redis的0号DB。

AOF 策略优点:

数据完整性和一致性更高,异常情况只会丢失1s的数据。

AOF 策略缺点:

AOF文件有冗余,文件太大,Redis启动加载慢。

Redis服务启动后执行载入程序时,优先判断是否开启了AOF持久化,如果时就载入AOF文件,否则载入RDB文件。

内存管理

Redis通过过期键处理和内存淘汰策略来管理内存。

过期键的处理

Redis可以设置键的过期时间,当这个键过期后,没有从Redis中清除,而是存在过期字典中,依然占用内存。对于过期键,Redis提供三种策略进行清除:

1.定时删除:在设置键的过期时间的同时,创建一个定时器(timer),让定时器在键过期时间来临时,立即执行对键的删除操作。这种策略,会对CPU造成压力,当设置时间键比较多的时候,那么会创建很多的定时器,会增加CPU的开销。

2.惰性删除:放任键过期不管,但是每次取键时判断键是否过期,如果过期就删除该键,否则返回键。这种策略对CPU压力不大,但是对内存压力大。如果有大量的过期键,但是没有这些键的访问,那么这些键依然保持在内存中,造成内存的浪费。

3.定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。

淘汰机制

1#maxmemory <bytes> 最大内存配置 2#maxmemory-policy noeviction 淘汰策略配置

Redis提供多种淘汰策略:

  • volatile-lru 淘汰过期key中上一回使用距离现在最久的。
  • allkeys-lru  同volatile-lru,但是针对所有的key。
  • volatile-lfu 淘汰过期key中使用频率最低的key。
  • allkeys-lfu 同上,但是针对所有key。
  • volatile-random 随机淘汰策略,针对过期key
  • allkeys-random 随机淘汰策略,针对所有key
  • volatile-ttl 淘汰剩余有效期最短的key
  • noeviction 不删除任意数据

默认的内存淘汰策略是noeviction,在Redis中LRU算法是一个近似算法。默认情况下,Redis随机挑选5个key,并且从中选取一个最近最久未使用的key进行淘汰,在配置文件中可以通过#maxmemory-samples的值来设置Redis需要检查key的个数,但是检查的越多,耗费的时间也就越久,但是越精准。

过期键删除策略和内存淘汰机制之间的关系:过期键删除策略强调的是对过期键的操作,如果键过期了,而内存还足够,不会使用内存淘汰机制,而这是也会使用过期键删除策略,删除过期键。内存淘汰机制强调的是对内存的管理,如果内存不够了,即使有的键没有过期,也要删除一部分,同时针对没有设置过期时间的键。

对比Memcached

1.Redis支持数据持久化,Memcached不支持,断电数据会消失。

2.Redis比Memcached支持更多的数据类型,Memcached所有值都是字符串。

所以优先选择Redis。

总结

本文介绍演示了Redis五种数据类型的操作,另外介绍了Redis RDB和AOF持久化策略,最后对比了Redis和Memcached。

参考

https://redis.io/

http://redisbook.com/preview/rdb/rdb_struct.html

https://juejin.im/post/5bd96bcaf265da396b72f855

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Opencv中Mat矩阵相乘——点乘、dot、mul运算详解

Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593