前面已经学习了redis的基本的命令行操作和数据类型,下面开始redis一些有趣的功能。

订阅和发布机制

  • 定义:发布者相当于电台,订阅者相当于客户端,客户端发到频道的消息,将会被推送到所有订阅此频道的客户端;客户端不需要主动去获取消息,只需要订阅频道,这个频道的内容就会被推送过来;

  • 作用:发布者和订阅者的解耦合可以带来更大的扩展性和更加动态的网络拓扑;

相关命令

# 订阅消息
subscribe 频道1 频道2 # 此时redis客户端会一直处于监听频道的状态,一有消息就处理;
# 取消订阅
unsubcribe 频道1 ... # 如果不写频道名称,则取消所有的订阅; # 推送消息
publish 频道1 消息内容

重点说明

  • 发布订阅机制一般使用在对同一个redis实例来说,实现类似于生产者消费者模式;

  • 在主从集群中,master发布的消息可以推送到slave中,但slave中的消息不能推送到master中;

订阅发布机制的不足:

  1. 如果消息接收方不能及时处理推送的消息,消息会在缓存队列中,会导致缓存占用的空间越来越大,最终导致redis崩溃;

  2. 发布的消息推送存在即时性,但网络一般是不稳定的,对于客户端来说,如果出现了断网的现象,那么接收的消息就会丢失,所以发布订阅模式不能用在对数据完整性要求高的场合;

简单的主从复制配置

  • 定义:一台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基础二的更多相关文章

  1. redis基础二----操作List类型

    1.lpush的使用方法 2.rpsuh的使用方法 3.删除元素 lrem中2值的是删除2个集合中的“b”元素 4. 通过上面的分析,redis中的list比较类型java的qunue队列

  2. redis基础二----操作set数据类型

    set集合是无序的,不能存在重复元素 bbb吃重复元素,是不能添加成功的 2 接下来分析zset,是有序的,你在添加的时候要指定元素的序列号 上面的 3 4 5 6 就是指定的元素的序列号 withs ...

  3. redis基础二----操作hash

    上面usr就是hash的名字,usr这个hash中存储了key 为id.name和age的值 一个hash相当于一个数据对象,里面可以存储key为id name age的值 2.批量插入一个hash数 ...

  4. Redis基础知识补充及持久化、备份介绍(二)--技术流ken

    Redis知识补充 在上一篇博客<Redis基础认识及常用命令使用(一)--技术流ken>中已经介绍了redis的一些基础知识,以及常用命令的使用,本篇博客将补充一些基础知识以及redis ...

  5. 【进阶之路】Redis基础知识两篇就满足(二)

    导言 大家好,我是南橘,一名练习时常两年半的java练习生,这是我在博客园的第二篇文章,当然,都是要从别处搬运过来的,不过以后新的文章也会在博客园同步发布,希望大家能多多支持^_^ 这篇文章的出现,首 ...

  6. Redis基础(二)数据库

    数据库 Redis服务器的所有数据库都保存在redisServer.db数组中,而数据库的数量则由redisServer.dbnum属性保存. struct redisServer { // .. / ...

  7. mysql主从复制、redis基础、持久化和主从复制

    一.mysql(mariadb)基础 1.基础命令(centos7操作系统下) 1.启动mysql systemctl start mariadb 2.linux客户端连接自己 mysql -uroo ...

  8. Redis基础用法、高级特性与性能调优以及缓存穿透等分析

     一.Redis介绍 Redis是一个开源的,基于内存的结构化数据存储媒介,可以作为数据库.缓存服务或消息服务使用.Redis支持多种数据结构,包括字符串.哈希表.链表.集合.有序集合.位图.Hype ...

  9. Redis系列(二):Redis的数据类型及命令操作

    原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...

随机推荐

  1. 模仿J2EE的session机制的App后端会话信息管理

    此文章只将思想,不提供具体完整实现(博主太懒,懒得整理),有疑问或想了解的可以私信或评论 背景 在传统的java web 中小型项目中,一般使用session暂存会话信息,比如登录者的身份信息等.此机 ...

  2. 正则化方法:L1和L2 regularization、数据集扩增、dropout(转)

    ps:转的.当时主要是看到一个问题是L1 L2之间有何区别,当时对l1与l2的概念有些忘了,就百度了一下.看完这篇文章,看到那个对W减小,网络结构变得不那么复杂的解释之后,满脑子的6666------ ...

  3. 纯Socket(BIO)长链接编程的常见的坑和填坑套路

    本文章纯属个人经验总结,伪代码也是写文章的时候顺便白板编码的,可能有逻辑问题,请帮忙指正,谢谢. Internet(全球互联网)是无数台机器基于TCP/IP协议族相互通信产生的.TCP/IP协议族分了 ...

  4. VMware虚拟机安装教程

    在实际的开发过程中,使用到VMware的时候是很多的.当你的电脑安装的是windows系统而想使用linux系统时,为了避免对本机的系统进行操作,那么安装虚拟机就是一项不错的选择. 在写这篇博文时,刚 ...

  5. MySQL .msi 安装失败改用.zip安装步骤

    一开始官网下载.msi安装包,安装到配置server时无法启动,长时间卡在这里,无法继续下去.上网看了一下解决办法,发现用.zip安装包进行安装比较简单可靠. 一.利用.msi安装包安装失败后的处理 ...

  6. 机器学习算法 - 支持向量机SVM

    在上两节中,我们讲解了机器学习的决策树和k-近邻算法,本节我们讲解另外一种分类算法:支持向量机SVM. SVM是迄今为止最好使用的分类器之一,它可以不加修改即可直接使用,从而得到低错误率的结果. [案 ...

  7. nyoj 63 小猴子下落 思维

    nyoj 63 小猴子下落 题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=63 思路: 不需要用指针创建二叉树,也不需要用数组来模拟二叉 ...

  8. caioj 1236 最近公共祖先 树倍增算法模版 倍增

    [题目链接:http://caioj.cn/problem.php?id=1236][40eebe4d] 代码:(时间复杂度:nlogn) #include <iostream> #inc ...

  9. centOS 搭建pipelineDB docs

    #下载docs git clone https://github.com/pipelinedb/docs.git #安装python-sphinx &python-dev yum instal ...

  10. 基于Jmeter的接口自动化测试实践

    在去年实施了一年的三端(PC.无线M站.无线APP[Android.IOS])后,今年7月份开始,我们开始进行接口自动化的实施,目前已完成了整个框架的搭建以及接口的持续测试集成.今天做个简单的分享. ...