超详细!Redis入门详解!

什么是Redis

​ Redis 是完全开源免费的,使用C语言编写的高性能NoSQL(非关系型数据库)数据库。基于Key-Value键值对的形式来存储数据, 其中Key是String类型,Value的类型较为丰富,下面我们专门介绍数据类型。

​ 与传统数据库不同的是Redis中的数据都是存储在内存中,所以读写效率非常高,并且数据还支持持久化,以及支持主从复制,集群,哨兵等多种架构模式。

Redis与Memcached的区别

先简单的介绍下Memcached的特点:

​ Memcached与Redis相同都是基于内存存储数据。

​ Memcached处理请求时使用的多线程异步IO方式,可以合理的利用CPU的多核优势,性能非常好。

​ Memcached可以对缓存的数据设置过期时间,过期后会清除掉。

​ 当内存存储容量不足时,会对缓存中过期的key进行清理。

​ Memcached的Key不能超过250个字节,Value不能超过1M;Key的最大失效时间是30天;以及只支持VK数据结构。

与Redis的区别:

​ Memcached使用多线程,主线程listen,多个worker子线程执行读写,可能会出现锁冲突。而Redis处理请求采用单线程模型,不需要考虑锁对性能的消耗。

​ Redis相比Memcached支持更丰富的数据结构及更丰富的数据操作。

​ Memcached所有数据都存储在内存中,断点后不能回复,而Redis提供了两种数据持久化的方式,可以保证数据的安全。

​ Redis天然支持高可用集群,而Memcached需要自己实现负载均衡算法解决集群问题。

​ 此外Redis还支持了Lua脚本,事务,主从等多种功能。

总结:在不考虑拓展性和持久性,并且只存储简单KV格式数据的情况下,推荐使用Memcached;在需要存储一些复杂数据,并且需要对数据进行处理以及对持久化有需求的时候,推荐使用Redis。

redis的安装

win安装

下载地址:https://github.com/tporadowski/redis/releases

下载安装包并解压。

开启cmd,进入到Redis的目录,执行

redis-server.exe redis.windows.conf

另起一个cmd,进入到redis的目录下,执行

redis-cli.exe -h 127.0.0.1 -p 6379
Linux安装

下载地址:http://redis.io/download

也可以直接使用命令安装

wget http://download.redis.io/releases/redis-xxx.tar.gz   #下载
tar xzf redis-xxx.tar.gz                                  #解压
cd redis-xxx    																					#进入到目录
make 																											#编译
cd src
./redis-server																						#启动Redis服务

注:这种方式启动使用的是默认配置,可以在启动的时候同时制定配置文件。

./redis-server ../redis.conf
./redis-cli
Docker安装
docker pull redis																	#拉取redis镜像
docker run -d --name redis --restart always -p 6379:6379 -v /usr/local/redis/data:/data redis --requirepass "123456" --appendonly yes 	  #创建Redis容器

为什么Redis的性能高

Redis基于内存操作,内存的读写速度非常快。

Redis是单线程模型,避免了不必要的上下文切换,不存在多线程切换的消耗。

采用了IO多路复用技术来处理并发连接,非阻塞IO使用epull实现,以及由epull + 内部实现的事件框架。epoll的读取,写入,关闭,连接都转换成事件,然后使用epoll的多路复用,不会浪费时间在IO上。

基础数据类型

String

注:Redis 中一个字符串值的最大容量是 512M。

String是Redis中最常使用的类型,一个Key对应一个Value,内部通过SDS实现,SDS类似Java中的ArrayList,通过预分配冗余空间开减少内存的频繁分配。

常用操作

set key value		添加键值对
get key					根据指定的key获取value
strlen key			根据指定的key获取value的长度
setnx key value 在key不存在的时候才设置这个键值对
incr key				将指定的key自增1
decr key 				指定key自减1
expire key time 设置key的过期时间,单位秒
ttl key 				查看指定key的过期时间
del key					删除指定key
127.0.0.1:6379> set t test
OK
127.0.0.1:6379> get t
"test"
127.0.0.1:6379> del t
(integer) 1
127.0.0.1:6379> set t 1
OK
127.0.0.1:6379> incr t
(integer) 2
127.0.0.1:6379> incr t
(integer) 3
127.0.0.1:6379> get t
"3"
127.0.0.1:6379> EXPIRE t 3
(integer) 1
127.0.0.1:6379> get t
(nil)
List

list是一个有序的双向链表,可以轻松的实现阻塞队列,可以使用左进右出的命令来完成队列的设计,生产者通过Lpush从左边插入,使用BRpop阻塞的抢尾部的数据。

127.0.0.1:6379> lpush t 1 2 3    #从左/右压如一个或多个值
(integer) 3
127.0.0.1:6379> lpop t					 #从左弹出一个值
"3"
127.0.0.1:6379> lpop t
"2"
127.0.0.1:6379> lpop t
"1"
127.0.0.1:6379> lpop t
(nil)
127.0.0.1:6379> LRANGE t 0 9      # 获取指定区间的元素
1) "6"
2) "5"
3) "4"
4) "3"
5) "2"
6) "1"
7) "3"
8) "2"
9) "1"
127.0.0.1:6379> BRPOP t 3						#弹出元素,指定超时时间
^[[A
(nil)
(3.08s)
Hash

类似java中Map的数据结构

127.0.0.1:6379> hset user id 1 name xiaoming    	#设置hash结构的值
(integer) 2
127.0.0.1:6379> hget user id											#获取指定的key
"1"
127.0.0.1:6379> hget user name 						
"xiaoming"
127.0.0.1:6379> hmget user id name								#获取指定key下多个值
1) "1"
2) "xiaoming"
127.0.0.1:6379> hgetall user											#获取指定key下所有值
1) "id"
2) "1"
3) "name"
4) "xiaoming"
127.0.0.1:6379> hdel user id 											#删除指定key
(integer) 1
127.0.0.1:6379> HEXISTS user id										#判断是否存在
(integer) 1
127.0.0.1:6379> hkeys user												#获取所有key
1) "name"
2) "id"
127.0.0.1:6379> HVALS user												#获取所有value
1) "xiaoming"
2) "1"
127.0.0.1:6379> HSETNX user id 2 									# 等同于String 中setnx,不存在才设置
(integer) 0
Set

set是无序集合,会自动去重。

127.0.0.1:6379> SADD t hello				#set中添加元素,重复的添加不上
(integer) 1
127.0.0.1:6379> SADD t hello
(integer) 0
127.0.0.1:6379> SADD t world
(integer) 1
127.0.0.1:6379> SMEMBERS t					#查看set中所有值
1) "hello"
2) "world"
127.0.0.1:6379> SISMEMBER t hello     #判断set中是否存在指定值
(integer) 1
127.0.0.1:6379> SCARD t								#获取set中元素个数
(integer) 2
127.0.0.1:6379> SREM t hello					#移除set中指定元素
(integer) 1
127.0.0.1:6379> SRANDMEMBER t 				#随机取出一个元素
"one"
127.0.0.1:6379> SMEMBERS t						
1) "hello"
2) "one"
3) "world"
127.0.0.1:6379> SRANDMEMBER t 2					#随机获取指定个数的元素
1) "world"
2) "one"
Sort Set

sort set是排序了的set,自动去重可以排序,在设置值的时候分配一个数值,自动根据分数排序

127.0.0.1:6379> zadd t 10 one
(integer) 1
127.0.0.1:6379> zadd t 2 two  3 three
(integer) 2
127.0.0.1:6379> ZRANGE t 0 -1				#小到大排序
1) "two"
2) "three"
3) "one"
127.0.0.1:6379> ZREVRANGE t 0 -1    #大到小排序
1) "one"
2) "three"
3) "two"
127.0.0.1:6379> ZRANGEBYSCORE t -inf +inf withscores   #显示全部数据及分数
1) "two"
2) "2"
3) "three"
4) "3"
5) "one"
6) "10"

持久化

Redis支持两种持久化机制,持久化就可以有效的避免因redis服务节点宕机而早晨的数据丢失问题,在下次重启的时候通过之前保存的持久化文件可实现数据的回复

RDB

RDB持久化过程分为两种:手动触发和自动触发

手动触发有save 和bgsave 命令;

save:会阻塞当前redis服务,知道RDB过程结束,其他的实例会有较长时间的阻塞;

bgsave:在Redis执行过程中去fork子进程,RDB的持久化过程由子进程负责,在持久化完成后自动结束,阻塞会发生在fork 操作时,不过时间较短。在执行bgsave的时候父进程会判断当前是否存在执行的持久化进程,如果存在bgsave直接返回。

RDB保存的都是数据的快照文件,默认是五分钟生成一次,也就是说在生成了RDB文件后到下次生成之间五分钟的数据可能会丢失。

RDB文件会保存在dir配置指定的目录下,文件名通过dbfilename指定。

优点:

RDB是一个紧凑压缩的二进制文件,记录了在某个时间点上的数据。非常适合全量复制场景,用于灾备。

RDB文件的回复速度较 AOF 要快。

缺点:

没办法做到实时数据备份,因为需要fork操作创建子进程。

文件使用特定的二进制格式存储,老版本无法兼容新版本RBD文件格式。

AOF

AOF以日志的方式记录每条写操作,主要解决了数据持久化的实时性。

开启AOF:appendonly yes

文件名通过参数appendfilename 配置,默认的文件名是appendonly.aof

AOF的工作流程是:写入命令->文件同步->文件重写->重启加载

所有的写命令都会先追加到 aof_buf 缓冲区中,因为Redis使用的单线程处理命令,如果每次写AOF文件都直接追加到硬盘那么性能会大大降低。

AOF文件的重写:有些已经超时的数据可能还一直保存在AOF文件中,通过重写机制保证AOF文件中的数据都是有效的,以及重写可以将多条命令进行合并如 lpush 多次就可以将其合并成一条指令。

AOF文件重写可以自动触发和手动触发;

手动触发调用 bgrewriteaof 命令

自动触发会根据配置的 auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数来配置触发的时间

auto-aof-rewrite-min-size:表示运行AOF重写时文件最小体积,默认 为64MB

auto-aof-rewrite-percentage:代表当前AOF文件空间 和上一次重写后AOF文件空间的比值。

两者对比

AOF相比RDB保存的数据更全。

相同数据量的时候AOF文件比RDB文件要打。

RDB文件的回复速度要比AOF快

混合模式

在Redis 4.0中新增了新的持久化模式 - 混合模式。这种模式结合了RDB和AOF的特点。

这个配置在 Redis中是默认关闭的,在配置文件中通过 aof-use-rdb-preamble 参数控制 yes 表示开启。

混合模式的持久化也是通过bgrewriteaof 完成的,不同的是,子进程是先将全量的数据以RDB的方式写入到AOF文件中,然后在将缓冲区中的增量命令以AOF的方式写入到文件中。

简单来说就是混合模式下的AOF文件中一部分是RDB格式的全量数据,从RDB后的数据都是AOF格式的增量数据。

内存淘汰策略

由于Redis是使用内存存储的数据,那么难免会遇到内存的瓶颈,当Redis内存超出限制的内存值时可以通过配置的淘汰策略删除相应的key,从而腾出空间继续工作;Redis中提供了六种淘汰策略:

volatile-lru:从设置了过期时间的数据中挑选最近最少使用的数据淘汰。

volatile-ttl:从设置了过期时间的数据中挑选即将过期的数据淘汰。

volatile-random:从设置了过期时间的数据中随机挑选任意数据淘汰。

allkeys-lru:在所有的数据中挑选出最近最少使用的数据进行淘汰。

allkeys-random:在所有的数据中挑选出任意数据进行淘汰。

no-enviction:禁止删除任何数据,当内存不足以插入新数据时,写入新的数据就会报错,可以保证数据不丢失,是系统默认的淘汰策略。

过期键的删除策略

当Redis中一个键过期了,并不是立即就从内存中删除的,而是通过三种不同的删除策略进行删除。

定时删除:在设置key过期时间的同时创建一个timer,定时器在key到达了过期时间时,立即删除(主动删除)。这种方式对内存较好,不过对cpu性能开销较大。

惰性删除:不去管过期键,当每次获取key时,在检查是否过期,如果过期了就删除,没过期就返回(被动删除)。这种方式对内存压力较大,会有较多的过期键不能及时的清理。

定期删除:每隔一段时间会对数据进行检查,删除其中的过期键,(主动删除)。对CPU和内存都折中的方式,可以通过限制操作执行的时间和频率来限制对CPU的影响。

持久化文件对于过期键的处理

在生成RDB文件的时候,如果发现key已经过期,是不会保存到RDB文件中的。

在从RDB文件恢复的时候,如果是master 节点那么会对RDB文件中所有的Key进行检查,会忽略已过期的key,不会载入到内存中。如果是slave节点那么不会校验key是否过期,全部载入到内存中。

对于AOF文件,如果一个key过期了,那么会向AOF文件中追加一条DEL命令,在重写AOF文件的过程中会检查key是否过期,过期的key不会加载到内存。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值