前言

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

演示环境

$ uname -a
Darwin 18.6. Darwin Kernel Version 18.6.: Thu Apr :: PDT ; root:xnu-4903.261.~/RELEASE_X86_64 x86_64
$ redis-server -v
Redis server v=5.0. sha=: malloc=libc bits= 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,可以通过下面的配置项修改:

bind 127.0.0.1 ::
port

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

$ redis-cli
127.0.0.1:>
127.0.0.1:> set hello world # 字符串操作
OK
127.0.0.1:> keys * # 列举所有的key
) "x1"
) "x2"
) "hello"
127.0.0.1:> hset myhash www #字典(哈希表)操作
(integer)
127.0.0.1:> hset myhash yyy
(integer)
127.0.0.1:>
127.0.0.1:>
127.0.0.1:> hgetall myhash # 获取字典myhash所有的key-value
) ""
) "www"
) ""
) "yyy"
127.0.0.1:> lpush mylist 1 # 列表操作,元素可以重复
(integer)
127.0.0.1:> lpush mylist
(integer)
127.0.0.1:> lpush mylist
(integer)
127.0.0.1:> lpush mylist
(integer)
127.0.0.1:> lrange mylist -
) ""
) ""
) ""
) ""
127.0.0.1:> sadd myset 1 #集合操作,重复元素只保留一个
(integer)
127.0.0.1:> sadd myset
(integer)
127.0.0.1:> sadd myset
(integer)
127.0.0.1:> sadd myset
(integer)
127.0.0.1:> smembers myset
) ""
) ""
) ""
127.0.0.1:> zadd mysortset redis #有序集合操作,前面的score值,作为排序的依据
(integer)
127.0.0.1:> zadd mysortset mysql
(integer)
127.0.0.1:> zadd mysortset memcached
(integer)
127.0.0.1:> zrange mysortset - withscores
) "redis"
) ""
) "memcached"
) ""
) "mysql"
) ""

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

u$ redis-cli -h
redis-cli 5.0. Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]]
-h <hostname> Server hostname (default: 127.0.0.1).
-p <port> Server port (default: ).

配置redis-server鉴权

requirepass foobared

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

$ redis-cli
127.0.0.1:>
127.0.0.1:> keys *
(error) NOAUTH Authentication required.
127.0.0.1:>

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

127.0.0.1:> auth foobared
OK
127.0.0.1:> keys *
) "myset"
) "mysortset"
) "x1"
) "mylist"
) "myhash"
) "x2"
) "hello"
127.0.0.1:>

持久化

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

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

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

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

$ redis-check-rdb dump.rdb
[offset ] Checking RDB file dump.rdb
[offset ] AUX FIELD redis-ver = '5.0.5'
[offset ] AUX FIELD redis-bits = ''
[offset ] AUX FIELD ctime = ''
[offset ] AUX FIELD used-mem = ''
[offset ] AUX FIELD aof-preamble = ''
[offset ] Selecting DB ID
[offset ] Checksum OK
[offset ] \o/ RDB looks OK! \o/
[info] keys read
[info] expires
[info] already expired

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

$ echo " i am test hahhahha" > dump.rdb
$ redis-server /usr/local/etc/redis.conf
:C Jul ::34.757 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
:C Jul ::34.757 # Redis version=5.0., bits=, commit=, modified=, pid=, just started
:C Jul ::34.757 # Configuration loaded
$ ps -ef|grep redis
:45下午 ttys002 :00.00 grep redis

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

$ rm dump.rdb
$ redis-server /usr/local/etc/redis.conf
:C Jul ::26.574 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
:C Jul ::26.574 # Redis version=5.0., bits=, commit=, modified=, pid=, just started
:C Jul ::26.574 # Configuration loaded
$ redis-cli
127.0.0.1:> keys *
(empty list or set)
127.0.0.1:>

另外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互补,它采用日志的形式记录每个写操作的内容,将写指令从前到后执行一次以完成数据的恢复工作。

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

清空Redis然后重启redis-server:

$ redis-cli
127.0.0.1:>
127.0.0.1:>
127.0.0.1:> keys *
(empty list or set)
127.0.0.1:>
127.0.0.1:>
127.0.0.1:> set hello world
OK $ cat appendonly.aof
*2 #表示有两个参数
$6 #该参数有6个字符
SELECT #参数是select
$1 #该参数有1个字符
0 #参数是0
*3 #表示有3个参数
$3 #该参数有3个字节
set #参数是set
$5 #该参数有5个字节
hello # 参数是hello
$5 #该参数有5个字节
world # 参数是world

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

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

淘汰机制

#maxmemory <bytes> 最大内存配置
#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

Redis配置讲解及实战的更多相关文章

  1. Asp.Net Core 2.0 项目实战(6)Redis配置、封装帮助类RedisHelper及使用实例

    本文目录 1. 摘要 2. Redis配置 3. RedisHelper 4.使用实例 5. 总结 1.  摘要 由于內存存取速度远高于磁盘读取的特性,为了程序效率提高性能,通常会把常用的不常变动的数 ...

  2. 小D课堂 - 零基础入门SpringBoot2.X到实战_第9节 SpringBoot2.x整合Redis实战_40、Redis工具类封装讲解和实战

    笔记 4.Redis工具类封装讲解和实战     简介:高效开发方式 Redis工具类封装讲解和实战         1.常用客户端 https://redisdesktop.com/download ...

  3. 小D课堂 - 零基础入门SpringBoot2.X到实战_第2节 SpringBoot接口Http协议开发实战_6、SpringBoot2.xHTTP请求配置讲解

    1.SpringBoot2.xHTTP请求配置讲解 简介:SpringBoot2.xHTTP请求注解讲解和简化注解配置技巧 1.@RestController and @RequestMapping是 ...

  4. Spring Data Redis 详解及实战一文搞定

    SDR - Spring Data Redis的简称. Spring Data Redis提供了从Spring应用程序轻松配置和访问Redis的功能.它提供了与商店互动的低级别和高级别抽象,使用户免受 ...

  5. SpringBoot2.x过滤器Filter和使用Servlet3.0配置自定义Filter实战

    补充:SpringBoot启动日志 1.深入SpringBoot2.x过滤器Filter和使用Servlet3.0配置自定义Filter实战(核心知识) 简介:讲解SpringBoot里面Filter ...

  6. spring boot 学习(十四)SpringBoot+Redis+SpringSession缓存之实战

    SpringBoot + Redis +SpringSession 缓存之实战 前言 前几天,从师兄那儿了解到EhCache是进程内的缓存框架,虽然它已经提供了集群环境下的缓存同步策略,这种同步仍然需 ...

  7. (万字好文)Dubbo服务熔断与降级的深入讲解&代码实战

    原文链接:(万字好文)Dubbo服务熔断与降级的深入讲解&代码实战 一.Dubbo服务降级实战 1 mock 机制 谈到服务降级,Dubbo 本身就提供了服务降级的机制:而 Dubbo 的服务 ...

  8. redis 配置

    一 Redis 支持写的指令 Redis大概的命令如下:set setnx setex appendincr decr rpush lpush rpushx lpushx linsert lset r ...

  9. redis配置详解

    ##redis配置详解 # Redis configuration file example. # # Note that in order to read the configuration fil ...

随机推荐

  1. 83.基于Vue SEO的四种方案(小结)

    前言:众所周知,Vue SPA单页面应用对SEO不友好,当然也有相应的解决方案,下面列出几种最近研究和使用过的SEO方案,SRR和静态化基于Nuxt来说. 1.SSR服务器渲染:2.静态化:3.预渲染 ...

  2. Linux中打开文件显示行号相关命令

    一.显示行号 :set number 或 :set nu 二.取消显示行号 :set nu! 三.每次打开显示行号 修改vi ~/.vimrc 文件,添加:set number

  3. Java 之 Redis 基础

    一.Redis 概述 1.什么是 Redis Redis:redis 是一款高性能的 NOSQL 系列的非关系型数据库. Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库, ...

  4. 一个工作13年的SAP开发人员的回忆:电子科技大学2000级新生入学指南

    让我们跟着Jerry的文章,一起回到本世纪初那个单纯美好的年代. 2000年9月,Jerry告别了自己的高中时代,进入到自己心目中的电子游戏大学,开始了四年的本科生活.每个新生,都拿到了这样一本薄薄的 ...

  5. Java 单文件、多文件上传 / 实现上传进度条

    博客地址:https://ainyi.com/76 日常,工作 在这里总结一下上传吧(是以前做过的练习,就汇总到个人博客吧) java ssm 框架实现文件上传 实现:单文件上传.多文件上传(单选和多 ...

  6. java requestmapping中关于路径的问题

    需要这种url写的方式才能映射

  7. kubernetes资源预留---转发

    下面内容还处于测试阶段,生产上是否能保证集群稳定暂时还不清楚.

  8. 面向切面编程AOP——加锁、cache、logging、trace、同步等这些较通用的操作,如果都写一个类,则每个用到这些功能的类使用多继承非常难看,AOP就是解决这个问题的,python AOP就是装饰器

    面向切面编程(AOP)是一种编程思想,与OOP并不矛盾,只是它们的关注点相同.面向对象的目的在于抽象和管理,而面向切面的目的在于解耦和复用. 举两个大家都接触过的AOP的例子: 1)java中myba ...

  9. HDU - 5571 :tree (动态点分治 异或)

    题意:给定一棵树,有点权a[],有边权. 现在有M次修改点权的操作,输出每次修改后,Σ(a[i]^a[j])*dis(i,j); 思路:因为待修改,我们需要快速得到以及修改一个点到其他所有点的信息. ...

  10. Ubuntu 14.04.2升级openssh7.9

    环境:Ubuntu 14.04.2 目的:openssh版本6.6升级为openssh7.9 准备以下3个包 http://www.zlib.net/ https://www.openssl.org/ ...