redis基础二
前面已经学习了redis的基本的命令行操作和数据类型,下面开始redis一些有趣的功能。
订阅和发布机制
定义:发布者相当于电台,订阅者相当于客户端,客户端发到频道的消息,将会被推送到所有订阅此频道的客户端;客户端不需要主动去获取消息,只需要订阅频道,这个频道的内容就会被推送过来;
作用:发布者和订阅者的解耦合可以带来更大的扩展性和更加动态的网络拓扑;
相关命令
# 订阅消息
subscribe 频道1 频道2 # 此时redis客户端会一直处于监听频道的状态,一有消息就处理;
# 取消订阅
unsubcribe 频道1 ... # 如果不写频道名称,则取消所有的订阅;
# 推送消息
publish 频道1 消息内容
重点说明
发布订阅机制一般使用在对同一个redis实例来说,实现类似于生产者消费者模式;
在主从集群中,master发布的消息可以推送到slave中,但slave中的消息不能推送到master中;
订阅发布机制的不足:
如果消息接收方不能及时处理推送的消息,消息会在缓存队列中,会导致缓存占用的空间越来越大,最终导致redis崩溃;
发布的消息推送存在即时性,但网络一般是不稳定的,对于客户端来说,如果出现了断网的现象,那么接收的消息就会丢失,所以发布订阅模式不能用在对数据完整性要求高的场合;
简单的主从复制配置
- 定义:一台redis服务器可以作为一个master,在其下面可以有多个slave,每个slave又可以作为一个master,从而可以构建庞大的redis数据库集群;
配置方法
方式一:修改配置文件
# 设置主服务器的配置,绑定固定的ip
sudo vi redis.conf
bind 服务器的ip
# 设置从服务器的ip
sudo vi redis.conf
bind 服务器的ip
slaveof 主服务器的ip 主服务器redis端口 # 注意,ip与端口之间使用空格分割
# 分别启动主从redis,主服务器redis负责写,也可以读;从服务器只能读,不能写;
方式二:使用命令行的方式动态设置
# 从服务器连接主服务器
slaveof host port
# 从服务器断开主服务器
slaveof no one
重要说明
从服务器与主服务器进行初始连接时,从服务器会丢弃所有的旧数据,然后载入主服务器的数据;
redis不支持主主复制,也就是说不可以两个redis相互设置对方为主服务器,虽然不会报错,但性能方面,以及对客户端的请求都可能出现问题;
redis复制的启动过程
- 当主服务器收到从服务器发送的复制请求的时候,主服务器执行的动作有:
等待从服务器的命令进入-->执行bgsave,创建快照文件;使用缓存区记录bgsave命令执行后所有的写命令-->快照文件创建完毕后,向服务器发送快照文件-->发送快照文件完毕后向从服务器发送缓存区的写命令-->完毕后每收到一个写命令就向从服务器发送
- 从服务器相应的动作有:
连接主服务器,发送sync命令-->等待响应-->丢弃所有的旧数据,载入主服务器的快照文件-->完成快照文件的解释,开始接受命令请求-->执行从主服务器发送的所有的写命令;
注意:redis支持主从链,即从服务器还可以有从服务器,但是从服务器A复制从服务器B的过程和从服务器B复制主服务器是有区别的;从服务器B向从服务器A发送完毕快照文件后,会先断开与从服务器A的连接,从服务器A需要重新连接并且请求同步;
redis的事务
redis有像关系型数据库一样的事务机制来保证多条命令作为原子操作;事务中的命令要么全执行,要么全不执行;
事务的完整过程:开始事务-->命令进入缓存-->执行事务;
事务的基本使用
# 开启一个事务
multi # 提交命令后,redis会将后面的操作保存起来
# 提交事务
exec # 提交命令后,redis会执行前面保存的所有的命令
# 取消事务
discard # 如果书写命令队列的过程中需要取消事务时使用
- redis事务中在写命令队列的时候,如果中间发生了语法错误,并且redis报了错,那么这个事务所有的命令都会取消执行;
> lpush list a b c
(integer) 3
> multi
OK
> lpush list d
QUEUED
> lpuxh list f
(error) ERR unknown command 'lpuxh'
> lrange list 0 10
QUEUED
> exec
(error) EXECABORT Transaction discarded because of previous errors.
> lrange list 0 10
1) "c"
2) "b"
3) "a"
# 所有的命令都没有执行
- 但有一些错误redis在执行之前并不能感知,这时redis会执行所有的的命令,客户端必须自己处理错误;
> lpush li blue red green
(integer) 3
> multi
OK
> get li
QUEUED
> lpush li white
QUEUED
> exec
1) (error) WRONGTYPE Operation against a key holding the wrong kind of value
2) (integer) 4
> lrange li 0 10
1) "white"
2) "green"
3) "red"
4) "blue"
# 所有的命令都执行了,只不过有的命令执行失败
注意点
redis的开启事务是将命令暂时保存在一个队列里,执行时依次操作;如果命令队列有一条出现语法错误,整个事务创建会失败;
redis没有提供事务的回滚功能,客户端必须自己处理失败的命令;
事务锁
# 基本命令
watch key key .. # 监控键值
# 取消对所有键的监控
unwatch
由于redis的事务中的命令其实是缓存队列,并且redis可以防止在事务的执行过程中有其他的命令插入,即具有隔离性;但是在多个客户端进行并发操作时存在数据无法同步的问题;如客户端A、B同时操作键key的值加一,预期结果为增加2,实际可能只有1.
为了解决这个问题,redis引入了watch监控键;
> watch num
OK
> set num 7
OK
> multi
OK
> set num 5
QUEUED
> exec
(nil)
> get num
"7"
- 可以看到事务并没有执行成功,wetch可以监控键,如果在监控后,键的值发生了改变,那么redis后面与这个键相关的事务操作将会失败,同时在exec执行后,键的监控会被取消;
注意:无论监控多少个键或事务中有没有与该键相关的命令,在最近的一个执行了exec,无论事务执行有没有成功,watch监控的所有键都将会取消,后面的事务不再受影响。
说明:使用watch监控实现并发修改键值,如果事务被取消,需要手动重新执行事务;
问题
- 以上可知,redis实现的是类似乐观锁(即预期并发时没有出现竞争修改同一个键值的状况),这种情况在并发量低时影响不大,但是高并发时几乎肯定出现竞争,并发修改键值程序重试的次数越来越多,资源被白白浪费,需要使用其他的方法实现悲观锁机制,这点后面会继续研究;
- 作者:天宇之游
- 出处:http://www.cnblogs.com/cwp-bg/
- 本文版权归作者和博客园共有,欢迎转载、交流,但未经作者同意必须保留此段声明,且在文章明显位置给出原文链接。
redis基础二的更多相关文章
- redis基础二----操作List类型
1.lpush的使用方法 2.rpsuh的使用方法 3.删除元素 lrem中2值的是删除2个集合中的“b”元素 4. 通过上面的分析,redis中的list比较类型java的qunue队列
- redis基础二----操作set数据类型
set集合是无序的,不能存在重复元素 bbb吃重复元素,是不能添加成功的 2 接下来分析zset,是有序的,你在添加的时候要指定元素的序列号 上面的 3 4 5 6 就是指定的元素的序列号 withs ...
- redis基础二----操作hash
上面usr就是hash的名字,usr这个hash中存储了key 为id.name和age的值 一个hash相当于一个数据对象,里面可以存储key为id name age的值 2.批量插入一个hash数 ...
- Redis基础知识补充及持久化、备份介绍(二)--技术流ken
Redis知识补充 在上一篇博客<Redis基础认识及常用命令使用(一)--技术流ken>中已经介绍了redis的一些基础知识,以及常用命令的使用,本篇博客将补充一些基础知识以及redis ...
- 【进阶之路】Redis基础知识两篇就满足(二)
导言 大家好,我是南橘,一名练习时常两年半的java练习生,这是我在博客园的第二篇文章,当然,都是要从别处搬运过来的,不过以后新的文章也会在博客园同步发布,希望大家能多多支持^_^ 这篇文章的出现,首 ...
- Redis基础(二)数据库
数据库 Redis服务器的所有数据库都保存在redisServer.db数组中,而数据库的数量则由redisServer.dbnum属性保存. struct redisServer { // .. / ...
- mysql主从复制、redis基础、持久化和主从复制
一.mysql(mariadb)基础 1.基础命令(centos7操作系统下) 1.启动mysql systemctl start mariadb 2.linux客户端连接自己 mysql -uroo ...
- Redis基础用法、高级特性与性能调优以及缓存穿透等分析
一.Redis介绍 Redis是一个开源的,基于内存的结构化数据存储媒介,可以作为数据库.缓存服务或消息服务使用.Redis支持多种数据结构,包括字符串.哈希表.链表.集合.有序集合.位图.Hype ...
- Redis系列(二):Redis的数据类型及命令操作
原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...
随机推荐
- 【python】Python的单例模式
原文:http://blog.csdn.net/ghostfromheaven/article/details/7671853 单例模式:保证一个类仅有一个实例,并提供一个访问他的全局访问点. 实现某 ...
- shopxx------list列表回显修改尝试
需求:在商品列表展示页面增加一列 一.修改模板 1.列表页面对应的freemarker模板位置 /shopxx/WebContent/WEB-INF/template/admin/product/li ...
- Spring Boot 的Maven多模块开发web项目使用外部容器进行部署
Spring Boot中自带有Tomcat容器,因此Spring Boot项目只需要运行main函数,就可以运行,但是以往的web项目,我们习惯于使用自己安装的Tomcat运行或者使用Tomcat.J ...
- Android 在通知栏实现计时功能
Notification是APP 向系统发出通知时,它将先以图标的形式显示在通知栏中.用户可以下拉通知栏查看通知的详细信息.我们可以在通知栏实现自定义的效果,也可以结合service和BroadCas ...
- 编译虚拟机jvm——openjdk的编译
java只所以被推广,实际上很大原因是因为本身是跨平台的,很大作用是因为虚拟机的关系. 一般情况下开发人员不需要关注虚拟机内部实现就可以日常开发了,但是有时候涉及到性能的时候就需要了解虚拟机的实现机制 ...
- 裸板驱动总结(makefile+lds链接脚本+裸板调试)
在裸板2440中,当我们使用nand启动时,2440会自动将前4k字节复制到内部sram中,如下图所示: 然而此时的SDRAM.nandflash的控制时序等都还没初始化,所以我们就只能使用前0~40 ...
- QuickTime视频解析问题
在QuickTime中可以解析出视频并播放视频,解析的格式后缀名为.mov,之后将该视频导入到Unity Project中,显示未解析到视频文件,本来应该会自动生成MovieTexture材质,但是并 ...
- codeforces 893B Beautiful Divisors 打表
893B Beautiful Divisors 思路: 打表 代码: #include <bits/stdc++.h> using namespace std; #define _for( ...
- 在网站开发中经常用到的javaScript技术
1>屏蔽功能类 1.1 屏蔽键盘所有键<script language="javascript"><!--function document.onkeyd ...
- calc() ---一个会计算的css属性
最近这个月一直在赶项目开发,遇到的问题和学到的前端知识没有更新到博客园,现在闲了下来,就整理一下前端知识. 在项目开发中,在样式这方面花费的时间较多,因为针对于数字的变化特别多,本人不爱记数字,在看设 ...