redis 的事务、锁、流水线

Redis与 mysql事务的对比
  • 开启 mysql:start transaction redis:multi
  • 语句:mysql:普通sql redis:普通命令
  • 成功:mysql:commit redis:exec
  • 失败: mysql:rollback redis:discard
在mutil后面的语句中, 语句出错可能有2种情况
  • 1: 语法就有问题,

    这种,exec时,报错, 所有语句得不到执行,这时事务保持原子性
  • 2: 语法本身没错,但适用对象有问题. 比如 zadd 操作list对象

    Exec之后,会执行正确的语句,并跳过有不适当的语句.这时事务没有保持原子性
redis 锁
  • 命令:watch key
  • Redis的事务中,启用的是乐观锁,只负责监测key没有被改动.如果有改动,则事务执行失败。此时事务有原子性。
  • 可以监视多个key,只要有一个改动,则事务都会执行失败
  • unwatch 作用: 取消所有watch监听
redis流水线
  • Redis客户端与Redis之间使用TCP协议进行连接,一个客户端可以通过一个socket连接发起多个请求命令。每个请求命令发出后client通常会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client,因此当执行多条命令的时候都需要等待上一条命令执行完毕才能执行,如:get ‘0’,get ‘1’,get ‘2’
  • 在大多数情况下,执行命令时的绝大部分时间都消耗在了发送命令和接收命令的过程中,因此减少客户与服务器之间的通信次数可以有效地提高程序的执行效率
  • 而管道(pipeline)可以一次性发送多条命令并在执行完后一次性将结果返回,pipeline通过减少客户端与redis的通信次数来实现降低往返延时时间,pipeline方式执行效率要比其他方式高10倍左右的速度;
  • 在执行pipeline()时传入True作为参数,或者不传入任何参数,那么客户端将使用MULTI和EXEC包裹起用户要执行的所有命令。如果传入False为参数,那么客户端同样会像执行事务那样收集用户要执行的所有命令,只是不再使用MULTI和EXEC包裹这些命令。如果用户需要向Redis发送多个命令,并且对于这些命令来说,一个命令的执行结果并不会影响另一个命令的输入,而且这些命令也不需要以事务的方式来执行的话,那么我们可以通过向pipeline()方法传入False来进一步提升Redis的整体性能
  • Pipeline虽然好用,但是每次Pipeline组装的命令个数不能没有节制,否则一次组装Pipeline数据量过大,一方面会增加客户端的等待时机,另一方面会造成一定的网络阻塞,可以将一次包含大量命令的Pipeline拆分成多次较小的Pipeline来完成.
性能测试
<?php
set_time_limit(0);
ini_set('memory_limit','1024M'); $redis = new Redis(); G('1');
$redis->connect('127.0.0.1');
//不具备原子性 ,管道
$redis->pipeline();
for ($i=0;$i<100000;$i++)
{
$redis->set("test_{$i}",pow($i,2));
$redis->get("test_{$i}");
}
$redis->exec();
$redis->close();
G('1','e'); G('2');
$redis->connect('127.0.0.1');
//事物具备原子性
$redis->multi();
for ($i=0;$i<100000;$i++)
{
$redis->set("test_{$i}",pow($i,2));
$redis->get("test_{$i}");
}
$redis->exec();
$redis->close();
G('2','e'); //普通
G('3');
$redis->connect('127.0.0.1');
//事物具备原子性
for ($i=0;$i<100000;$i++)
{
$redis->set("test_{$i}",pow($i,2));
$redis->get("test_{$i}");
}
$redis->close();
G('3','e'); function G($star,$end = '')
{
static $info = array();
if (!empty($end))
{
$info[$end] = microtime(true);
$sconds = $info[$end] - $info[$star];
echo $sconds,"ms<br/>"; } else {
$info[$star] = microtime(true);
}
}
//测试输出的结果:
0.043839931488037ms
0.4456958770752ms
0.45916604995728ms

redis--->事务和锁的更多相关文章

  1. redis事务,分布式锁

    事务:一组命令集合 主要命令multi 和exec multi set a 1 sadd s1 a ...... exec 错误处理 (1)语法错误 127.0.0.1:6379> multi ...

  2. Redis事务及锁应用

    Redis只支持简单的事务,不像mysql那样比较完整严格,对数据的完整性也维持的很好.redis的开启事务实际上只是将开启事务之后的一段命令用队列包裹起来了,当调用redis的执行命令(exec)全 ...

  3. redis 事务(悲观锁和乐观锁)

    MULTI 开启事务,后续的命令会被加入到同一个事务中 事务中的操作会发送给客服端,但是不会立即执行,而是将操作放到了该事务对应的一个队列中,服务端返回QUEQUD EXEC 执行EXEC后,事务中的 ...

  4. 分布式缓存技术redis学习系列(三)——redis高级应用(主从、事务与锁、持久化)

    上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性. 安全性设置 设置客户端操作秘密 redis安装 ...

  5. 分布式缓存技术redis学习(三)——redis高级应用(主从、事务与锁、持久化)

    上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性.目录如下: 安全性设置 设置客户端操作秘密 客户 ...

  6. Redis事务和分布式锁

    Redis事务 Redis中的事务(transaction)是一组命令的集合.事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都执行,要么都不执行.Redis事务的实现需要用到 MUL ...

  7. 分布式缓存技术redis系列(三)——redis高级应用(主从、事务与锁、持久化)

    上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性. 安全性设置 设置客户端操作秘密 redis安装 ...

  8. 一篇和Redis有关的锁和事务的文章

    部分参考链接 Transaction StackExchange.Redis Transaction hashest 正文 Redis 是一种基于内存的单线程数据库.意味着所有的命令是一个接一个的执行 ...

  9. redis 事务 & 锁

    参考:https://www.cnblogs.com/DeepInThought/p/10720132.html Redis不保证原子性:Redis中,单条命令是原子性执行的,但事务不保证原子性,且没 ...

  10. redis事务机制和分布式锁

    Redis事务机制 严格意义来讲,Redis的事务和我们理解的传统数据库(如mysql)的事务是不一样的:Redis的事务实质上是命令的集合,在一个事务中要么所有命令都被执行,要么所有事物都不执行.  ...

随机推荐

  1. JavaScript递归注意事项

    var svg_node = document.getElementById("svgnode") function parents(posnode,selector) { var ...

  2. TCP/IP||UDP广播和多播

    1.概述 广播和多播应用于UDP,TCP是一个面向连接协议,意味着分别运行与两个主机内的两进程间存在一个连接,在考虑多个主机内的共享通信网络,每个以太网帧包含源主机和目的主机以太网地址(48bit), ...

  3. 自荐一个 element 表单代码生成器

    Element UI 表单设计及代码生成器,可将生成的代码直接运行在基于 Element 的 vue 项目中. github仓库   https://github.com/JakHuang/form- ...

  4. `docker数据持久化volume和bind mounts两种方式

    将数据从宿主机到容器的三种方式: ,volumes:docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)保存数据的最佳方式 ,bind mounts 将宿主机上的任 ...

  5. linux大盘格式化分区

    Linux 实例的磁盘管理 对于 Linux 系统上的大磁盘,也要采用 GPT 分区格式, 也可以不分区, 把磁盘当成一个整体设备使用. 在 Linux 上一般采用 XFS 或者 EXT4 来做大盘的 ...

  6. Java提供的JDBC标准- 六大步骤

    JDBC 1.//加载驱动 class.forname 2.//创建连接connection 3.//创建 管道流 statement或  preparestatement预处理4.//执行sql语句 ...

  7. 【题解】Comet OJ Round 70 简要题解

    [题解]Comet OJ Round 70 简要题解 A 将放在地上的书按照从小到大排序后,问题的本质就变成了合并两个序列使得字典序最小.可以直接模拟归并排序.直接用循环和std::merge实现这个 ...

  8. 洛谷$P3620\ [APIO/CTSC 2007]$数据备份 贪心

    正解:贪心 解题报告: 传送门$QwQ$ $umm$感觉这种问题还蛮经典的,,,就选了某个就不能选另一个这样儿,就可以用堆模拟反悔操作 举个$eg$,如果提出了$a_i$,那就$a_{i-1}$和$a ...

  9. 1093 字符串A+B (20 分)C语言

    给定两个字符串 A 和 B,本题要求你输出 A+B,即两个字符串的并集.要求先输出 A,再输出 B,但重复的字符必须被剔除. 输入格式: 输入在两行中分别给出 A 和 B,均为长度不超过 10^​6的 ...

  10. SpringCloudAlibaba通过jib插件打包发布到docker仓库

    序言 在SpringBoot项目部署的时候,我了解到了Jib插件的强大,这个插件可以快速构建镜像发布到我们的镜像仓库当中去.于是我打算在毕设当中加上这个功能,并且整合到github actions中去 ...