redis知识

一:reids的基础知识

1.启动redis: ./reids.server /xx/xx/redis.conf

2.检测reids是否启动成功: ./reids.cli -p 6379 (6379为redis的默认端口号)

输入Ping恢复pong表示成功。

3.redis默认是16个库,select x (x表示索引 0-15)命令切换数据库

库的索引从0开始,select 1表示切换到第二个库。

redis的库数量可以在reids.conf文件中修改定义:如下图

4.dbsize命令查看当前数据库的key的数量,keys * 查询当前库所有的数据, keys k?查询当前库所有以k开头的数据

5.flushdb:清空当前库数据,flushall:清空全部库数据

二.redis的五大数据类型

  1. redis String (字符串)
  2. redis Hash (哈希)
  3. redis list (列表)
  4. redis set (集合)
  5. redis zset (sorted set:有序集合)

2.常见的redis数据类型操作命令:http://redisdoc.com/

三.redis数据类型的常用命令

Redis键(key) :

keys *

exists key的名字判断某个key是否存在(1/0)

move key db –> 丛当前库中移除指定的k到指定的库中: move k2 2 (把当前库中的k2移除到第3个数据库中)

expire key 秒钟:为给定的key设置过期时间

ttl key 查看还有多少秒过期,-1表示永不过期、-2表示已过期

type key 查看你的Key是什么类型

Redis 字符串(String) :

set/get/del/append/strlen append k2 123 //在 k2后面最近123

Incr/decr/incrby/decrby,一定要是数字才能进行加减

getrange/setrange 取范围内的值/设置范围内的值: getrange k2 0 2/setrange k2 0 xxx

setex(set with expire) :setex k2 10 k2 //设置k2十秒后过期删除

setnx(set if not exist):setnx k2 123 //判断k2是存在,不存在则设置它的值为123

mset/mget/msetnx :设置/获取多个值/多个不存在:mset k1 v2 k2 v2 /mget k1 k2/msetnx k1 v1 k2 v2

getset(先get再set)

Redis列表(List):

lpush/rpush/lrange

lpop/rpop出站。(从前面开始【正顺】/从后面开始【反顺】)

lindex,按照索引下标获取元素(从上到下) lindex list01 1

llen 长度

lrem list删除n个value : lrem list01 1 3 (就是删除集合中的1个3)

ltrim list 开始index 接收index,截取指定范围的值然后赋值给key (就是截取集合中1-3索引的值):list=1234 ,ltrim list 1 3 结果为:234

rpoplpush 源列表 目的列表

lset key index value : 对集合指定的索引赋值

linsert key before/after 值1 值2 把某个值插入到某个Key的前面或者后面

Redis集合(Set)

sadd/smembers/sismember

scard ,获取集合里面有多少个元素

srem key value 删除集合中的元素

srandmember key 某个整数(随机出几个数):srandmember set 3,在set这个集合中随机去除3个数据

spop key 随机出栈 (比如:spop set01 即从set01中随便“移除”一个值出来)

smove key1 key2 ,作用是将key1里面的某个‘移除值赋值’给key2

sdiff:差集、sinter:交集、sunion:并集

Redis哈希(Hash)

kv模式不变,但是v是一个键值对

hset/hget/hmget/hgetall/hdel : hset user id 11:设置user里面的id为11

hlen

hexists key 在key里面是否存在某个值的key (1/0)

hkeys/hvals 单独获取hash里面的Key或value : hkeys user

hincrby/hincybyfloat

hsetnx : hsetnx user id 11(判断user里面是否存在id,存在则不出返回0,否则新增id 11,返回1)

Redis有序集合(zset)

在set基础上加了一个score值,之前set是 k1 v1 v2 v3

现在zset是 k1 score1 v1 score2 v2

zadd/zrange/zrange withscores

zrangebyscore key 开始score 结束score

“(“表示不包含,limit表示从第几个开始取值,取多少个

zrem key ,某score下对应的value值,作用是删除元素

zcard 获取长度

zcount key score 区间, 获取区间大小

zrank key values :获取下标值

zscore key : 对应值获取对应分数(通过v 获取 score)

zrevrank key values 值 :作用是逆序获取下标值

zrevrange:作用是反转zset里面的,比如: 13 –》31

zrevangebyscore key 和zrangebyscore 相反:zrevangebyscore key 90 60 ,zrangebyscore key 60 90

四:redis配置文件介绍

INCLUDES:可以通过includes包含,redis.conf可以作为总闸,包含其他

GENERAL:

SNAPSHOTTING:

save : 保存快照,数据保存至dump.rdb文件中

stop-writes-on-bgsave-error yes(默认yes)(stop-writes-on-bgsave-error:如果保存错误那么前台停止写)

如果配置成no,表示你不在乎数据的一致性或者有其他手段发现和控制

rdbcompression yes:对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话redis将采用laf算法进行压缩。如果你不想消耗cpu来进行压缩的话,可以设置为No

rdbchecksum yes : 在存储快照后,还可以让redis使用crc64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以设置为no

dbfilename dump.rdb : 备份文件的名称默认为:dumo.rdb

dir ./ :文件目录

五:redis的持久化

1:rdb(Redis DataBase)

官方介绍:

在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的**Snapshot**快照,

​ 它恢复时是将快照文件直接读到内存里。

是什么:

​ Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中。

​ 待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。

​ 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能

​ 如果需要进行大规模的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比

​ AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。

Fork:

​ 作用是复制一个与当前进程一样的进程。新进程的所有数据、数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程

Redis保存的文件:

​ dump.rdb

配置位置:

​ 配置文件中的:Snapshot

含义:

三种行为触发一个就执行保存操作:

  1. 900秒内(15分钟),如果至少更换了一个key

  2. 300秒内(5分钟),如果至少10个key发生变化

  3. 60秒内,发生10000个key更改

    禁用RDB策略释放:save “”

    在执行shutdow命令是会立马生产快照dump.rdb文件

    flushall命令也会产生dump.rdb,但里面是空的无意义

    save:save时只管保存快照,其他不管,全部阻塞

    bfsave:redis会在后台异步进行快照操作,快照同时还可以响应客户端请求

    可以通过lastsave命令获取最后一次成功执行快照的时间

假如有些数据非常重要更改后要求立马备份,那么就直接执行save,如图:

如何停止:

动态所有停止RDB保存规则的方法:redis-lic config set save “”

2:aof (Append Only File)

appendonly no 默认为no,开启为Yes

appendfilename “appendonly.aof” aop数据存储数据文件名

aop三个属性

no: 不要fsync,只要让操作系统在需要的时候刷新数据就行了。更快。(不同步,设置数据时自行设置更新)
always: fsync after every write to the append only log. Slow, Safest.(每次写入仅追加日志后fsync。慢点,最安全。)
everysec: fsync only one time every second. Compromise.(每秒钟只同步一次)

默认为:appendfsync everysec

aof的重写功能:

auto-aof-rewrite-percentage 100 (默认是文件的一倍:100)
auto-aof-rewrite-min-size 64mb (默认文件大小)

— 即:当appendonly.aof文件的内容大于64的一倍时,进行重写。(压缩)

六:redis的主从复制:(一主二从,主写从读)

REPLICATION

配置规则:配从不配主

replicaof masterip masterport – masterid:主redis的地址,masterport:主redis的端口

masterauth master-password – 如果主机有设置密码,那么这个地方一定要写上主机的密码

配置后启动reids服务查看如下

role:master 表主服务器,slave表从服务器

connected_slaves:1 表示有1个从服务器连接

等等信息

七:哨兵模式:

为什么要哨兵模式:

​ 简单理解即主从模式会存在主从宕机问题,这个时候就需要程序自己去发现然后去选举新的主服务。

reids安装目录中有个:

sentinel.conf文件这个就是配置哨兵模式的文件

port 26379 为默认端口

protected-mode no 这个参数请和redis.conf配置保持一致

bind 127.0.0.1这个参数请和redis.conf配置保持一致

daemonize no 这个设置为yes 即开启后台运行开启

logfile “xx.log” 这个为哨兵日志文件配置

dir /tmp 为文件存储地址 默认为:/tmp

sentinel monitor master-name ip redis-port quorum

​ master-name :为主机名称 一般为:mymaster

​ ip :为主机ip地址

​ redis-port: 为主机端口

​ quorum :选举投票数,即有多少票通过则表示认定主机宕机,然后开始选举新的主机

sentinel monitor mymaster 127.0.0.1 6379 2

sentinel auth-pass master-name password

​ 若主机有密码则设置此项没有则不用设置,若设置那么主从的密码一定要一致

sentinel down-after-milliseconds master-name milliseconds

sentinel down-after-milliseconds mymaster 30000

主机在30s内无法访问,则认定为宕机。

sentinel parallel-syncs master-name numreplicas

**sentinel parallel-syncs mymaster 1

主从转移要有多少个主副本,这里设置为1,数量越多耗时越长。

sentinel failover-timeout master-name milliseconds

**sentinel failover-timeout mymaster 180000

指定故障转移超时(毫秒)默认是3分钟

从服务的配置和主服务器配置一样,但port 要改。且端口一定要开放

八:内存淘汰策略

redis的数据已经设置了TTL(过期删除策略),并不是过期时间一到就会立马删除的。这个需要从redis的过期策略说起:

过期策略

1.定时删除:

redis会为每个设置了过期时间的key设置一个定时器,只要过期时间一到定时器就会立马去删除数据,

这样做的好处是:内存利用率很好,但是很耗cpu.(10W+的数据10W+的定时器,那cpu还不累死)

Redis 默认会每秒进行十次过期扫描,过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略。

  1. 从过期字典中随机 20 个 key;
  2. 删除这 20 个 key 中已经过期的 key;
  3. 如果过期的 key 比率超过 1/4,那就重复步骤 1;

同时,为了保证过期扫描不会出现循环过度,导致线程卡死现象,算法还增加了扫描时间的上限,默认不会超过 25ms。

如果某一时刻,有大量key同时过期,Redis 会持续扫描过期字典,造成客户端响应卡顿,因此设置过期时间时,就尽量避免这个问题,在设置过期时间时,可以给过期时间设置一个随机范围,避免同一时刻过期。

redis的定时任务默认是1s执行10次(100ms一次,值越大说明刷新频率越快,最Redis性能损耗也越大),如果要修改这个值,可以在redis.conf中修改hz的值。

redis.conf中,hz默认设为10,提高它的值将会占用更多的cpu,当然相应的redis将会更快的处理同时到期的许多key,以及更精确的去处理超时。 hz的取值范围是1~500,通常不建议超过100,只有在请求延时非常低的情况下可以将值提升到100。

1.2 单线程的redis,如何知道要运行定时任务?

redis是单线程的,线程不但要处理定时任务,还要处理客户端请求,线程不能阻塞在定时任务或处理客户端请求上,那么,redis是如何知道何时该运行定时任务的呢?

Redis 的定时任务会记录在一个称为最小堆的数据结构中。这个堆中,最快要执行的任务排在堆的最上方。在每个循环周期,Redis 都会将最小堆里面已经到点的任务立即进行处理。处理完毕后,将最快要执行的任务还需要的时间记录下来,这个时间就是接下来处理客户端请求的最大时长,若达到了该时长,则暂时不处理客户端请求而去运行定时任务。

2.惰性删除:

redis中设置了过期时间的key不会立马去删除,而是在下一次被访问的时候redis去判断这个key是否过期,过期则不会返回任何数据,没过去则返回数据。

这样做的好处是:cpu利用很有好,内存利用率就没有那么友好了。

3.定期删除

这个过期策略就是上面2中方法的折中方案,redis会将每个设置了过期时间的key放入到一个独立的字典中,以后会定期的遍历整个字典来删除到期的key,redis默认会每秒进行10次过期扫描,

过期扫描不会遍历过期字典中所有的key,而是采用一个简单的贪心策略。

1.从过期字典中随机20个key;

2.删除这20个key中已经过期的key;

3.如果过期的key比率超过了1/4.那就重复步骤1

redis默认是每隔 100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载。

过期策略存在的问题:

1.定时策略很耗cpu基本不会使用

2.惰性删除耗内存,如果有些过期的key一直没有被返回就会一直占用内存

3.定期删除,方法1,2的折中方案,但是也会存在内存问题即:有些过期的key一直没有被随机删除到。

正是基于这类问题而产生了一个保底方案那就是“内存淘汰策略”。

内存淘汰策略:

1.noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键。(默认使用)

2.allkeys-lru:加入键的时候,如果过限,首先通过LRU算法淘汰掉最久没有使用的键。

3.volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中淘汰掉最久没有使用的键

4.allkeys-random:加入键的时候如果过限,从所有key随机删除

5.volatile-random:加入键的时候如果过限,从过期键的集合中随机淘汰

6.volatile-ttl:从配置了过期时间的键中淘汰马上就要过期的键

7.volatile-lfu:从所有配置了过期时间的键中淘汰使用频率最少的键

8.allkeys-lfu:从所有键中淘汰使用频率最少的键

内存策略怎么配置?默认大小是多少?

Maxmemory 配置指令

所述maxmemory配置指令,以便用于配置Redis的使用的存储器的指定量的数据集。可以使用redis.conf文件设置配置指令,或者稍后在运行时使用CONFIG SET命令。

例如,为了配置 100 兆字节的内存限制,可以在redis.conf文件中使用以下指令。

1
maxmemory 100mb

设置maxmemory为零会导致没有内存限制。这是 64 位系统的默认行为,而 32 位系统使用 3GB 的隐式内存限制。

当达到指定的内存量时,可以在不同的行为中进行选择,称为策略。Redis 可以只为可能导致使用更多内存的命令返回错误,或者它可以逐出一些旧数据以便在每次添加新数据时返回到指定的限制。

驱逐政策

maxmemory达到限制时,Redis 的确切行为是使用maxmemory-policy配置指令配置的。