Redis项⽬实战(⼀)--redis基础
redis(Remote Dictionary Server)
⼀、原理及特性层⾯:
1、优势:
1)数据加载在内存中,执⾏速度快,数据结构类似于HashMap,HashMap的优势就是查和操作的时间复杂度都是O(1)。
2)单线程多路复⽤,I/O多路复⽤(防⽌ I/O 阻塞)-- ⼀种效率更⾼的 I/O 模型,在单个线程中通过记录跟踪每⼀个sock(I/O流)的状态来管理多个I/O流。(相⽐多线程效率更⾼, .跟多线程相⽐较,线程切换需要切换到内核进⾏线程切换,需要消耗时间和资源, I/O多路复⽤不需要切换线/进程)
3)协议简单,客户端和服务端使⽤ RESP协议(容易实现、快速解析), RESP是⼆进制安全的⽽且从⼀个进程发块数据给另⼀个进程的时候不需要做转换,因为他会在块数据之前加上长度。
*2
$3
GET
$4
name
2、特点及应⽤:
0)⽀持lua脚本,在Redis中,执⾏Lua语⾔是原⼦性,也就是说Redis执⾏Lua的时候是不会被中断的,具备原⼦性,这个特性有助于Redis对并发数据⼀致性的⽀持。
1)⽀持事务、 watch,操作命令都是原⼦的。
Redis事务: Redis中的事务(transaction)是⼀组命令的集合。 Redis保证⼀个事务中的所有命令要么都执⾏,要么都不执⾏。如果在发送EXEC命令前客户端断线了,则Redis会清空事务队列,事务中的所有命令都不会执⾏。⽽⼀旦客户端发送了EXEC命令,所有的命令就都会被执⾏,即使此后客户端断线也没关系,因为Redis中已经记录了所有要执⾏的命令。 Redis的事务还能保证⼀个事务内的命令依次执⾏⽽不被其他命令插⼊。
注意:和传统的mysql事务不同的事,redis事务不⽀持回滚。
Redis Watch 命令⽤于监视⼀个(或多个) key ,如果在事务执⾏之前这个(或这些) key 被其他命令所改动,那么事务将被打断(为了避免竞态条件,或多线程其的情况)
//伪代码
WATCH key
isFieldExists = HEXISTS key, field
if isFieldExists is 1
MULTI
HSET key, field, value
EXEC
else
UNWATCH
return isFieldExists
2)⽀持管道Pipline,批量指令操作操作,能减少⽹络交互时间;
缺陷:允许⼀定⽐例的写⼊失败,对可靠性要求很⾼的系统不适⽤;
3)⽀持消息发布与订阅;
缺陷:相对于kafka,redis吞吐量不⾼,redis接收端挂掉重启,不会接收之前发送的消息。
4)可以设置key的过期时间;
5)⽀持5种数据类型;
6)⽀持数据持久化;
7)⽀持主从(master-slave)复制来实现数据备份,主机会⾃动将数据同步到从机。
⼆、基本使⽤
1、redis创建⽤户
//创建普通⽤户****
useradd -d /appdeploy -m appdeploy
//创建⽤户组并加⼊刚刚创建的⽤户****
useradd -g appdeploy -n appdeploy(可不执⾏)
//修改⽂件或⽂件夹的权限,使新增⽤户可以拥有该⽂件的查看权限****
chmod -R 777 /usr/local/soft/elasticsearch-6.4.0/
或者授权⽂件归属于另⼀个⽤户组的⽤户(chown -R appdeploy:appdeploy /usr/local/soft/elasticsearch-6.4.0)
//将⽤户添加到⽤户组⽽不脱离该⽤户原来的组
usermod -a -g groupA appdeploy(可不执⾏)
//将⽂件夹的归属给某个组
chown root:mygroup /user/local/soft(可不执⾏)
2、redis启动
前端启动:在redis的安装⽬录下直接启动redis-server
./redis-server
后台启动:
把/root/redis-3.0.f复制到/usr/local/redis/bin⽬录下
f /usr/local/redis/bin/
修改配置⽂件:
./f
查看redis进程:
ps aux|grep redis
如下信息:
root 5190 0.1 0.3 33936 1712 ? Ssl 18:23 0:00 ./redis-server *:6379
root 5196 0.0 0.1 4356 728 pts/0 S+ 18:24 0:00 grep redis
指定端⼝启动(&表⽰后台运⾏)
./redis-server --port 6380&
3、Redis-cli
//默认连接localhost运⾏在6379端⼝的redis服务。
./redis-cli
//指定IP和端⼝连接
//-h:连接的服务器的地址
//-p:服务的端⼝号
./redis-cli -h 192.168.25.153 -p 6379
关闭redis:
.
/redis-cli shutdown
//设置密码的连接⽅式
./redis-cli -h 127.0.0.1 -p 6379 -a Passw0rd
4、五种数据类型
1). String String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字。
2).Hash Hash是⼀个string类型的field和value的映射表,hash特别适合⽤于存储对象。⽐如我们可以Hash数据结构来存储⽤户信息,商品信息等等。
3).List list就是链表,Redis list的实现为⼀个双向链表,即可以⽀持反向查和遍历。
应⽤:
使⽤Redis实现消息队列
普通队列:⼀般使⽤list结构作为队列,rpush⽣产消息,lpop消费消息, blpop阻塞消费。
消费多次:⽣产⼀次消费多次的情况使⽤发布/订阅模式延时队列:使⽤sortedset,拿时间戳作为score,消息内容作为key调⽤zadd来⽣产消息,消费者⽤zrangebyscore指令获取N秒之前的数据轮询进⾏处理
4).Set set是可以⾃动排重的。
5).Sorted Set sorted set增加了⼀个权重参数score,使得集合中的元素能够按score进⾏有序排列。
设置key的过期时间。
Expire key second:设置key的过期时间
Ttl key:查看key的有效期
Persist key:清除key的过期时间。Key持久化。
> expire Hello 100
(integer) 1
> ttl Hello
(integer) 77
Incr
对 key 的值做加加操作,并返回新的值。注意 incr ⼀个不是 int 的 value 会返回错误,incr ⼀个不存在的 key,则设置 key 为 1
应⽤:
Redis实现限制访问频率,限制每个⽤户每分钟最多只能访问100个页⾯。
实现思路:⽤户每次访问将value的值通过INCR命令⾃增1.如果⾃增后的值是1同时设置过期时间为1分钟。这样⽤户每次访问的时候都读取该键的值,如果超过了100就表明该⽤户的访问频率超过了限制,需要提⽰⽤户稍后访问。且该键每分钟会⾃动被删除。所以下⼀分钟⼜会重新计算,也就达到了限制访问频率的⽬的。
其他命令:
incrby
同 incr 类似,加指定值,key 不存在时候会设置 key,并认为原来的 value 是 0
Decr
对 key 的值做的是减减操作,decr ⼀个不存在 key,则设置 key 为-1
Decrby
同 decr,减指定值。
Append
给指定 key 的字符串值追加 value,返回新字符串值的长度。
Strlen
取指定 key 的 value 值的长度。
persist xxx(取消过期时间)
选择数据库(0-15库)
Select 0 //选择数据库
move age 1//把age 移动到1库
Randomkey随机返回⼀个key
Rename重命名
Type 返回数据类型
6、持久化⽅案:
RDB:快照形式,定期把内存中当前时刻的数据保存到磁盘,Redis默认⽀持的持久化⽅案。速度快但是服务器断电的时候会丢失部分数据。
AOF:append only file。把所有对redis数据库操作的命令,增删改操作的命令。保存到⽂件中。数据库恢复时把所有的命令执⾏⼀遍即可。两种持久化⽅案同时开启使⽤AOF⽂件来恢复数据库.能保证数据的完整性,但是速度慢。
两者如何选择?
1. 如果redis仅仅是⽤来做为缓存服务器的话,我们可以不使⽤任何的持久化(建议redis启动时进⾏全量数据同步或定时全量同步);
2. ⼀般情况下我们会将两种持久化的⽅式都开启。redis优先加载AOF⽂件来回复数据。RDB的好处是快速(推荐);
3. 在主从节点中,RDB作为我们的备份数据,只在salve(从节点)上启动,同步时间可以设置的长⼀点,只留(save 900 1)这条规则就可以
了;
4. 开启AOF的情况下,主从同步是时候必然会带来IO的性能影响,此时我们可以调⼤auto-aof-rewrite-min-size的值,⽐如5GB。来减少
IO的频率;
5. 不开启AOF的情况下,可以节省IO的性能影响,主从节点通过RDB持久化同步,但如果主从都挂掉,影响较⼤。
三、Redis缓存、ehcache、memcached⽐较
特点:
ehcache直接在jvm虚拟机中缓存,速度快,效率⾼;但是缓存共享⿇烦,集分布式应⽤不⽅便。
memcache保存在内存,⽀持分布式,只存储String类型数据,不⽀持持久化。
redis是通过socket访问到缓存服务,效率⽐ecache低(相差⼀个数量级),⽐数据库要快很多,⽀持数据类型较为丰富,⽀持集和分布式缓存,有成熟的⽅案。
技术选型:
单个应⽤,降低应⽤的复杂性或者对缓存访问要求很⾼的应⽤,⽤ehcache。
如果是⼤型系统,存在缓存共享、分布式部署、缓存内容很⼤的,建议⽤redis。
memcache,⽼牌缓存服务,相关领域⽀持⽐较丰富,window和linux都可以使⽤。
补充下:ehcache也有缓存共享⽅案,不过是通过RMI或者Jgroup多播⽅式进⾏⼴播缓存通知更新,缓存共享复杂,维护不⽅便;简单的共享可以,但是涉及到缓存恢复,⼤数据缓存,则不合适。
redis内存淘汰策略:
⾼版本的Redis中当内存达到极限时,内存淘汰策略主要采⽤了6种⽅式进⾏内存对象的释放操作
1).volatile-lru:从设置了过期时间的数据集中,选择最近最久未使⽤的数据释放
2).allkeys-lru:从数据集中(包括设置过期时间以及未设置过期时间的数据集中),选择最近最久未使⽤的数据释放
3).volatile-random:从设置了过期时间的数据集中,随机选择⼀个数据进⾏释放
4).allkeys-random:从数据集中(包括了设置过期时间以及未设置过期时间)随机选择⼀个数据进⾏⼊
释放
redis支持的五种数据类型5).volatile-ttl:从设置了过期时间的数据集中,选择马上就要过期的数据进⾏释放操作
6).noeviction:不删除任意数据(但redis还会根据引⽤计数器进⾏释放呦~),这时如果内存不够时,会直接返回错误
默认的内存策略是noeviction,在Redis中LRU算法是⼀个近似算法,默认情况下,Redis随机挑选5个键,并且从中选取⼀个最近最久未使⽤的key进⾏淘汰,在配置⽂件中可以通过maxmemory-samples的值来设置redis需要检查key的个数,但是栓查的越多,耗费的时间也就越久,但是结构越精确(也就是Redis从内存中淘汰的对象未使⽤的时间也就越久~)。
LRU算法简单介绍:
1)LRU算法作为内存管理的⼀种有效算法,其含义是在内存有限的情况下,当内存容量不⾜时,为了保证程序的运⾏,这时就不得不淘汰内存中的⼀些对象,释放这些对象占⽤的空间。
2)LRU (英⽂:Least Recently Used), 意为最近最少使⽤,如果⼀块数据最近被访问,那么它将来被访问的⼏率也很⾼,根据数据的历史访问来淘汰长时间未使⽤的数据。
3)在操作系统中LRU算法淘汰的不是内存中的对象,⽽是页,当内存中数据不⾜时,通过LRU算法,选择⼀页(⼀般是4KB)将其交换到虚拟内存区(Swap区)。
借鉴了不少⽂章,感谢各路⼤神分享,转载请注明出处,谢谢:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论