Redis高级

Linux环境下的Redis

在Linux环境中安装redis

下载安装包

# wget http://download.redis.io/releases/redis-?.?.?.tar.gz

解压

tar -xvf 文件名.tar.gz

编译

make

安装

make install

启动Redis服务

直接启动

  • 进入redis下的src目录,打开redis-server
# redis-server [port]
  • 打开redis-cli
# redis-cli [-h host] [-p port]

指定配置文件启动*

  • 编写指定配置文件 xxx.conf

  • 打开服务时指定

# redis-server [配置文件]

持久化

什么是持久化

利用永久性存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为永久化。

持久化的方式

  • 将当前数据状态进行保存,快照形式,存储数据结果,存储格式简单,关注点在数据(RDB)
  • 将数据的操作过程进行保存,日志形式,存储操作过程,存储格式复杂,关注点在数据的操作过程(AOF)

RDB方式

命令

save    //作用:手动执行一次保存操作
bgsave  //作用:手动启动后台保存操作,但不是立即执行
save second changes     //作用:在一定时间内key的数量变化达到指定值时自动执行持久                         化,后台是bgsave
特殊形式:
debug reload    //服务器运行过程中保存
shutdown save   //关闭服务器时指定保存数据

注意:save指令的执行会阻塞当前Redis服务器,直到当前RDB过程完成为止,有可能会长时间阻塞,线上环境不建议使用;而bgsave是针对save阻塞问题做的优化,通过调用linux中的fork函数生成子进程保存,Redis中所有涉及到RDB操作都采用bgsave的方式,save命令可以放弃使用。

save指令的相关配置

  • dbfilename dump.rdb

    说明:设置本地数据库文件名,默认值为dump.rdb

    经验:通常设置为dump-端口号.rdb

  • dir

    说明:设置存储.rdb文件的路径

    经验:通常设置成存储空间较大的目录中,目录名称data

  • rdbcompression yes

    说明:设置存储至本地数据库时是否压缩数据,默认为yes,采用LZF压缩

    经验:通常默认为开启状态,如果设置为no,可以节省CPU运行时间,但会使存储的文件变大(巨大)

  • rdbchecksum yes

    说明:设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行

    经验:通常默认为开启状态,如果设置为no,可以节约读写性能过程约10%时间消耗,但是存在一定的数据损坏风险

  • stop-writes-on-bgsave-error yes

    说明:后台存储过程中如果出现错误现象,是否停止保存操作(bgsave的配置)

    经验:通常默认为开启状态

对比

方式 save指令 bgsave指令
读写 同步 异步
阻塞客户端指令
额外内存消耗
启动新进程

RDB的优缺点

优点:

  • RDB时一个紧凑压缩的二进制文件,存储效率较高
  • RDB内部存储的时redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景
  • RDB恢复数据的速度要比AOF快很多
  • 应用:服务器中没X消失执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复

缺点:

  • RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大可能性丢失数据
  • bgsave指令每次运行要执行fork操作创建子进程,要牺牲掉一些性能
  • Redis的众多版本中未进行RDB文件格式的版本同一,有可能出现各版本之间数据格式无法兼容现象

AOF方式

概念

  • AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时重新执行AOF文件中的命令已达到恢复数据的目的。与RDB相比可以简单描述为将记录数据转变为记录数据产生的过程。
  • AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方案。

AOF写数据的三种策略

  • always(每次)

    每次写入操作均同步到AOF文件中,数据零误差,性能较低

  • everysec(每秒)

    每秒将缓冲区中的指令同步到AOF文件中,数据准确性较高,性能较高

    在系统突然宕机的情况下丢失1秒内的数据

  • no(系统控制)

    由操作系统控制每次同步到AOF文件的周期,整体过程不可控

AOF功能开启

  • 配置
appendonly yes|no       //是否开启AOF持久化功能,默认为不开启状态
appendfsync always|everysec|no      //AOF写数据策略
appendfilename filename     //AOF持久化文件名,默认文件名为appendonly.aof,建议                               配置为appendonly-端口号.aof

AOF重写

作用

  • 降低磁盘占用量,提高磁盘利用率
  • 提高持久化效率,降低持久化写时间,提高IO性能
  • 降低数据恢复用时,提高数据恢复效率

AOF重写方式

  • 手动重写
bgrewriteaof
  • 自动重写
auto-aof-rewrite-min-size size
auto-aof-rewrite-percentage percentage

RDB与AOF对比

持久化方式 RDB AOF
占用存储空间 小(数据级:压缩) 大(指令级:重写)
存储速度
恢复速度
数据安全性 会丢失数据 依据策略决定
资源消耗 高/重量级 低/轻量级
启动优先级

事务

简介

Redis事务就是一个命令执行的队列,将一系列预定义命令包装成一个整体(一个队列)。当执行时,一次性按照添加顺序依次执行,中间不会被打断或者干扰。

总结:一个队列中,一次性、顺序性、排他性的执行一系列命令。

事务的基本操作

multi       //设置事务的开启位置,此指令执行后,后续的所有指令均加入到事务中
exec        //设置事务的结束位置,同时执行事务。与multi成对出现,成对使用
discard     //终止当前事务的定义,发生在multi之后,exec之前

注意:已经执行完毕的命令对应的数据不会自动回滚,需要程序员在代码中实现回滚。

事务锁:

watch key1 [key2...]    //对key添加监视锁,在执行exec前如果key发生了变化,终止事                          务执行
unwatch                 //取消对所有key的监视

分布式锁:

setnx lock-key value    //使用setnx设置一个公共锁
del lock-key            //删除一个公共锁
添加时间设定的锁:
expire lock-key second
pexpire lock-key milliseconds

​ 利用setnx命令的返回值特征,有值返回则设置失败,无值返回则设置成功:

​ 1.对于返回设置成功的,拥有控制权,进行下一步的具体业务操作

​ 2.对于返回设置失败的,不具有控制权,排队或等待


删除策略

数据删除策略

Redis中数据的特征

Redis是一种内存级数据库,所有数据均存放在内存中,内存中的数据可以通过TTL指令获取其状态

  • XX:具有时效性的数据
  • -1:永久有效的数据
  • -2:已经过期的数据或被删除的数据、未定义的数据

Redis中时效性数据的存储结构

image-20200303190313869.png

目标

在内存占用与CPU占用之间寻找一种平衡,顾此失彼都会造成整体redis性能的下降,甚至引发服务器宕机或内存泄漏


定时删除

  • 创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务立即执行对键的删除操作。
  • 优点:节约内存,到时就删除,快速释放掉不必要的内存占用
  • 缺点:CPU压力很大,无论CPU此时负载多高,均占用CPU,会影响Redis服务器响应时间和指令吞吐量
  • 总结:用处理器性能换取存储空间

惰性删除

  • 数据到达过期时间,不做处理,等下次访问该数据时删除
  • 优点:节约CPU性能,发现必须删除的时候才删除
  • 缺点:内存压力很大,出现长期占用内存的数据
  • 总结:用存储空间换取处理器性能

定期删除

* Redis启动服务器初始化时,读取配置server.hz的值,默认为10
* 每秒钟执行server.hz次 serverCron() -> databaseCron() -> activeExpireCycle()
* activeExpireCycle()对每个expire[*](每个数据库对应一个expire)逐一进行检测,每  次执行250ms/server.hz
* 对某个expires[*]检测时,随机挑选W个key检测
      * 如果key超时,删除key
      * 如果一轮中删除的kshaney的数量>W*25%,循环该过程
      * 如果一轮中删除的kshaney的数量≤W*25%,检查下一个expire[\*],0-15循环
      * W取值=ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP属性值
* 参数current_db用于记录activeExpireCycle()进入哪个expire[*]执行
  • 周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度
  • 特点1:CPU性能占用设置有峰值,检测频度可以自定义设置
  • 特点2:内存压力不是很大,长期占用内存的冷数据会被持续清理
  • 总结:周期性抽查存储空间

在Redis中,同时使用 惰性删除 与 定期删除 两种策略。


数据逐出策略

什么是逐出算法

Redis使用内存存储数据,在执行每一个命令前,会调用freeMemoryIfNeeded()检测内存是否充足。如果内存不满足新加入数据的最低存储要求,redis会临时删除一些数据为当前指令清理内存空间。清理数据的策略称为逐出算法。

注意:逐出数据的过程不是100%能够清理出足够的可使用的内存空间,如果不成功则反复执行。当对所有数据尝试完毕后,如果不能达到内存清理的要求,将出现错误信息。

影像数据逐出的相关配置

maxmemory           //最大可使用内存,为物理占用内存的比例,默认0,生产环境中一般                    设置50%以上
maxmemory-samples   //每次选取待删除数据的个数
maxmemory-policy    //达到最大内存后的逐出策略

可选的逐出策略:

  • 检测易失数据(可能会过期的数据集server.db[i].expires)
  1. volatile-lru:挑选最近使用时间最少的数据
  2. volatile-lfu:挑选最近使用次数最少的数据
  3. volatile-ttl:挑选将要过期的数据
  4. volatile-random:任意选择数据
  • 检测全库数据(所有数据集server.db[i].dict)
  1. allkeys-lru:挑选最近使用时间最少的数据
  2. allkeys-lfu:挑选最近使用次数最少的数据
  3. allkeys-random:任意选择数据
  • 放弃数据驱逐
  1. no-enviction:禁止驱逐,会引发OOM

服务器配置

基础配置

daemonize yes|no            //设置服务器以守护进程的方式运行
bind 127.0.0.1              //绑定主机地址
port 6379                   //设置服务器端口号
databases 16                //设置数据库数量

日志配置

loglevel debug|verbose|notice|warning       //设置服务器的日志级别
logfile 端口号.log                          //日志记录文件名

客户端配置

maxclients 0                //设置同一时间最大客户端连接数
timeout                     //客户端闲置等待最大时常,达到最大值后关闭连接,关闭                             设置为0

多服务器快捷配置

include /path/server-端口号.conf   //导入并加载指定配置文件信息
include /path/server-端口号.conf   //导入并加载指定配置文件信息

高级数据类型

Bitmaps

简介

Redis提供了Bitmaps这个“数据结构”可以实现对位的操作。 把数据结构加上引号主要因为:

  • Bitmaps本身不是一种数据结构,实际上它就是字符串,但是它可以对字符串的位进行操作。
  • Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同。 可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量。

总结:设置对应的bit串,每一位的0/1值作为判定条件。如1010001,每一位对应一个用户是否访问。

操作

getbit key offset               //获取指定key对应偏移量上的bit值
setbit key offset value         //设置指定key对应偏移量上的bit值,取0或1
bitcount key [start end]        //计算指定key中1的数量
bitop op destkey key1 [key2...] //对指定key进行位运算并将结果保存在destkey中
    op的取值:and|or|not|xor

HyperLogLog

简介

HyperLogLog是用于统计基数的。

基数:集合去重后的元素个数。如:{1,3,5,7,5,7,8}的基数为{1,3,5,7,8}

操作

pfadd key element [element...]              //添加数据
pfcount key [key...]                        //统计数据
pfmerge destkey sourcekey [sourcekey...]    //合并数据

注意:

  • 用于进行基数统计,不是集合,不是保存数据,只记录数量而不是记录数据
  • 核心是基数估算算法,最终数值存在一定误差
  • 误差范围:基数估计是结果是一个带有0.81%标准错误的近似值
  • 耗空间极小,每个HyperLogLog key占用了12K的内存用于标记基数
  • pfadd命令不是一次性分配12K内存使用,会随着基数的增加内存而增大
  • pfmerge命令合并后占用的存储空间为12K,无论合并之前数据量多少

GEO

简介

GEO可以用于存储位置信息。

操作

geoadd key longitude latitude member [longitude latitude member...]           //添加坐标点
geopos key member [member...]       //获取坐标点
geodist key member1 member2 [unit]  //计算坐标点距离
georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count]            //根据坐标求范围内的数据
georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count]            //根据点求范围内的数据
geohash key member [member...]      //获取指定点对应的坐标hash值
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352