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 命令参考.这 ...
随机推荐
- 来手撸一个小小小小小"3D引擎"
开始的唠叨 说是3D引擎确实有点过于博眼球了,其实就是实现了一个透视投影,当然也不是那么简单的. 此篇文章是纯粹给小白看的 高手请勿喷 .也称之为小向带你图形学入门基础 . 哇哈哈哈哈 一说到做一个3 ...
- Python 学习之路2
这是我在大学上机实验的作业 实验一 将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. 首先,先谈下我的设计思路: 设计思路: 1. 先需判断输入的number是不是一个数字( ...
- 万能动态库调用工具IDMA(InvokeDllMethodsAdvance)
万能动态库调用工具IDMA 开发者:马兆瑞 QQ/微信:624762543 百度云下载链接:https://pan.baidu.com/s/1skW5W4H CSDN下载链接:http://d ...
- Android 在通知栏实现计时功能
Notification是APP 向系统发出通知时,它将先以图标的形式显示在通知栏中.用户可以下拉通知栏查看通知的详细信息.我们可以在通知栏实现自定义的效果,也可以结合service和BroadCas ...
- C语言之计算log2
#include<stdio.h>int main(){int num,count=0,i=0,ret=0;scanf("%d",&num);count=num ...
- ios多线程开发总结
1>无论使用哪种方法进行多线程开发,每个线程启动后并不一定立即执行相应的操作,具体什么时候由系统调度(CPU空闲时就会执行). 2>更新UI应该在主线程(UI线程)中进行,并且推荐使用同步 ...
- sql server 2008 r2 登陆时显示无法打开默认的数据库
解决! 第一步: 远程其他服务器的数据库能连上,本地的数据库某个用户名就是打不开,一开始以为是用户名或者密码错误, 后来用sqlcmd dos命令 -S . -U an -P sa 的方式登陆时可以的 ...
- input required
HTML <input> required 属性 HTML <input> 标签 实例 带有必填字段的 HTML 表单: <form action="demo ...
- Java并发编程总结4——ConcurrentHashMap在jdk1.8中的改进
一.简单回顾ConcurrentHashMap在jdk1.7中的设计 先简单看下ConcurrentHashMap类在jdk1.7中的设计,其基本结构如图所示: 每一个segment都是一个HashE ...
- Protocol Buffer序列化对比Java序列化.
初识 Protocol Buff是谷歌推出的一种序列化协议. 而Java序列化协议也是一种协议. 两者的目的是, 将对象序列化成字节数组, 或者说是二进制数据, 那么他们之间有什么差异呢. proto ...