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 命令参考.这 ...
随机推荐
- 七、VueJs 填坑日记之渲染一个列表
在上一篇博文中,我们对vue组件有了一个简单的认识和大概的理解.在之前认识项目结构的时候,我们在/src目录中创建了一个components的文件夹,而今天就要用到了,这个文件夹的作用就是放置我们的自 ...
- 企业级应用TOMCAT
第1章 Tomcat 1.1 Tomcat简介 Tomcat是一个免开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不多的场合下被普遍使用,是开发调试JSP程序的首选,另 ...
- Java实现Html转PDF的方法
写在前面 以下路径问题根据项目结构自己修改,以下是我使用spring boot打成jar包的写法. 一.需求背景 在前端编辑器中输入任意的文本,包括css样式变化,保存为html文本.通过Java后台 ...
- JS获取URL参数的值
function getQueryValue (key) { const reg = new RegExp('(^|&)' + key + '=([^&]*)(&|$)', ' ...
- HTML5学习指导路线
HTML5是现在热门的技术,经过8年的艰苦努力,该标准规范终于制定完成,在这里为想要学习HTML5初级程序员详细划分一下学习内容和步骤,让大家清楚的知道HTML5需要学什么?能够快速掌握HTML5开发 ...
- SQL---索引---创建索引
CREATE INDEX 语句用于在表中创建索引. 在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据. 索引 您可以在表中创建索引,以便更加快速高效地查询数据. 用户无法看到索引,它们只 ...
- java二进制相关基础
转载请注明原创出处,谢谢! 说在前面 之前在JVM菜鸟进阶高手之路十(基础知识开场白)的时候简单提到了二进制相关问题,最近在看RocketMQ的源码的时候,发现涉及二进制的内容蛮多,jdk源码里面也是 ...
- NodeJS爬虫入门
1. 写在前面 往常都是利用 Python/.NET 语言实现爬虫,然现在作为一名前端开发人员,自然需要熟练 NodeJS.下面利用 NodeJS 语言实现一个糗事百科的爬虫.另外,本文使用的部分代码 ...
- Python学习之--socket续集
IO多路复用: I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. 一个很简单的linux例子,select,poll, ...
- 在Github上面搭建一个自己域名的Hexo博客
前言 在一次看到别人的博客主页,觉得设计很漂亮.但是由于自己对于前台这块没什么办法,煞是羡慕.偶然中发现这种样式是在Github上面搭建的,使用的是Next主题.于是便想自己也搭建一个,于是便去就去查 ...