Redis事务

Redis 通过 MULTI 、EXEC、 DISCARD  和 WATCH 四个命令来实现事务功能。

MULTI :标记一个事务块的开始。

EXEC: 执行所有事务块内的命令。

DISCARD :取消事务,放弃执行事务块内的所有命令。

WATCH key [key ...] :监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

一、事务

1、是什么?

可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,不许加塞!

2、能干什么?

一个队列中,一次性的、顺序性的、排他性的执行一系列的命令。要么一起成功,要么一起失败。排好队,一次性的执行多个redis的命令!

3、怎么玩?

通过MULTI指令开启,之后输入多个命令!Redis将它们加入到队列当中,所有的命令通过EXEC来开启执行!通过DISCARD来放弃本次的批处理操作!

(1)正常执行(好比购物先加入购物车,最后EXEC统一结账。)

192.168.1.66:6379> MULTI    --开启事务
OK
192.168.1.66:6379> set k1 v1
QUEUED
192.168.1.66:6379> set k2 v2
QUEUED
192.168.1.66:6379> set k3 v3
QUEUED
192.168.1.66:6379> set k4 v4
QUEUED
192.168.1.66:6379> get k2
QUEUED
192.168.1.66:6379> EXEC --结束事务
1) OK
2) OK
3) OK
4) OK
5) "v2"

(2)DISCARD 撤销所有操作!

192.168.1.66:6379> MULTI
OK
192.168.1.66:6379> set k1 11
QUEUED
192.168.1.66:6379> set k2 22
QUEUED
192.168.1.66:6379> set k3 33
QUEUED
192.168.1.66:6379> DISCARD
OK
192.168.1.66:6379> get k1 --这里的k1的value值还是上面的值,而不是新设置的value值
"v1"

(3)加入队列时不出错,下面的都将正常运行,执行时出错不影响其他语句!

192.168.1.66:6379> set k1 v1
OK
192.168.1.66:6379> set k2 v2
OK
192.168.1.66:6379> MULTI
OK
192.168.1.66:6379> incr k1
QUEUED
192.168.1.66:6379> set k2 22
QUEUED
192.168.1.66:6379> EXEC
1) (error) ERR value is not an integer or out of range --在运行是才发现k1不是数字,报错
2) OK --执行成功

注意:
   (1)当遇到执行错误时,redis放过这种错误,保证事务执行完成。(所以说redis的事务并不是保证原子性)
   (2)与mysql中事务不同,在redis事务遇到执行错误的时候,不会进行回滚,而是简单的放过了,并保证其他的命令正常执行。这个区别在实现业务的时候,需要自己保证逻辑符合预期。
   (3)当事务的执行过程中,如果redis意外的挂了。很遗憾只有部分命令执行了,后面的也就被丢弃了。当然如果我们使用的append-only file方式持久化,redis会用单个write操作写入整个事务内容。即是是这种方式还是有可能只部分写入了事务到磁盘。发生部分写入事务的情况 下,redis重启时会检测到这种情况,然后失败退出。可以使用redis-check-aof工具进行修复,修复会删除部分写入的事务内容。修复完后就 能够重新启动了。

Redis主从复制

一、环境搭建

     既然是主从复制,那肯定需要多个redis服务器,下面我先创建3个服务器,的端口号分别是:6379、6380、6381。

  1、复制默认配置文件redis.conf,放到rediszhucong文件夹中,并重命名。

根据每个端口号不同,重新配置conf文件

(1)端口号

(2)开启线程守护

(3)Pid文件名字

(4)Log文件名字

(5)Dump.rdb名字

2、在redis-server目录下,读取配置启动这三个redis

    ./redis-server ../../rediszhucong/redis6379.conf
./redis-server ../../rediszhucong/redis6380.conf
./redis-server ../../rediszhucong/redis6381.conf

查看进程

  3、打开多个界面进行操作

./redis-cli -p 6379
./redis-cli -p 6380
./redis-cli -p 6381

成功打开三个服务器

二、主从复制

   1、是什么?

行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主。

  2、 能干嘛?

   读写分离,更加安全,性能提升。

3、怎么玩?

一主二仆、薪火相传、反客为主

(1)一主二仆

  1. 配从不配主
  2. slaveof 主库ip 主库端口

我这里把6379当成主库,所以只要在6380和6381端口输入:

通过info replication 查看是否配置成功。

可以看到6379端口服务器,role角色是master,同时下面有两个从服务器

再看6380端口,role显示为slave。

总结:

(1)如果master服务器挂了,那么6380,和6381角色依旧是slave

(2)如果master又好了,那么一切正常,下面还是有两个从,自己还是主。

(3)如果slave服务器挂了,那么重启后,需要重新slaveof 选择master,除非在配置文件中配置

 (2)薪火相传

新火相传的意思其实就是去中心化,现在只有80和81两台slave连接master,假如,有100台slave的话,那么master就压力很大了,所以redis又推出了新火相传的解决方案,上一台slave,可以下一台slave的master.

79和80不改变,在81上配置如下:

127.0.0.1:6381> SLAVEOF 127.0.0.1 6380
OK

(3)反客为主

上面提到了,当master死机的时候,重写启动还是master,现在时,我是想当master死机的时候,让某一台从机变成主机,这里是,让80变成主机,

只要当master死机器的时候,手动在80执行如下命令:

127.0.0.1:6380> SLAVEOF no one

同时,81也要重新配置,配置80为主机

127.0.0.1:6381> SLAVEOF 127.0.0.1 6380
OK

三、哨兵模式

虽然说,反客为主,已经不错了,但总不能一旦master挂掉,我在手动去重新配置主服务器,和slave服务器吧。

简单的说,哨兵模式就是反客为主的自动版,通过监控主机,当主机挂掉的时候,就几台从机中透过投票选出新的主机

  1、在 /etc/redis/目录下新建一个sentinel.conf文件(这个目录随意,但名字一定叫sentinel.conf)

里面的内容为:

sentinel monitor host6379 127.0.0.1 6379 1 

意思是6379端口的服务器是现在的master,host6379是自己任意取的名字,上面最后一个数字1,表示主机挂掉后salve投票看让谁接替成为主机,得票数多少后成为主机

 2、启动sentinel.conf 文件

./redis-sentinel ../sentinel.conf 

表示成功!

这是注意:

 就是当原来的master回来后,不是做独立的mater,而是做新主机的slave

当我输入:SHUIDOWN命令,代表kill端口的redis,当我重新启动6379端口后,发现他的角色变成了:slave

二、WATCH

WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。

被 WATCH 的键会被监视,并会发觉这些键是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回空多条批量回复(null multi-bulk reply)来表示事务已经失败。

1、首先我们不加WATCH进行事务处理

时间

客户端A

客户端 B

说明

T1

SET name aa

SET age  10

GET name

aa

GET age

10

数据库中两客户端登录,及键初始值。

它们是同步的。

T2

MULTI

SET name bb

Incr age

 

此时,客户端1开启事务,并提交队列命令:

1.想要将当前age自增+1运算;

2.将name值改为bb

T3

 

SET name cc

Incr age

此时,客户端2修改了age值

同时修改name值为cc

T4

EXEC

 

T5

GET name

bb

GET age

12

此时,客户端1执行队列命令,发现运算之后age不是理想中的11,而是12原因是被其它客户插足抢先给修改了。name值确实是没有被其它所改变。这样可能导致数据不一致性。

2、添加WARCH

客户端1-引入“乐观锁”机制 客户端2 说明
 SET age
"10"
 SET name
"zhangsan"

 GET age
"10"
 GET name
"zhangsan"
数据库中两客户端登录,及键初始值。
 WATCH    age name
OK
 MUTLI
OK
 incr age
QUEUED
 set name lisi
QUEUED
  此时,客户端1用watch命令监视age和name,然后开启事务,并提交队列命令
   incr age
(integer) 11
此时,客户端2修改了age值

 exec
(nil)
 get age
"11"
 get name
"zhangsan"
  此时,客户端1执行队列命令,由watch监控发现此期间age的值已经被修改过,则让事整个务回滚,不做任何动作。

watch可以同时监控多个键,在监控期间只要有一个键被其它客户端改变,则整个事务回滚。

Redis(3)---Redis事务|主从复制的更多相关文章

  1. Redis数据库 02事务| 持久化| 主从复制| 集群

    1. Redis事务 Redis不支持事务,此事务不是关系型数据库中的事务: Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的 ...

  2. Redis主从、事务、哨兵、消息、代理分片

    安装 wget http://download.redis.io/releases/redis-3.0.5.tar.gz tar -zxvf redis-3.0.5.tar.gz cd redis-3 ...

  3. 01 . Redis简介及部署主从复制

    简介 Remote Dictionary Server, 翻译为远程字典服务, Redis是一个完全开源的基于Key-Value的NoSQL存储系统,他是一个使用ANSIC语言编写的,遵守BSD协议, ...

  4. Redis系列之key操作命令与Redis中的事务详解(六)

    序言 本篇主要目的有二: 1.展示所有数据类型中key的所有操作命令,以供大家学习,查阅,更深入的挖掘redis潜力. 2.掌握redis中的事务,让你的数据完整性一致性拥有更优的保障. redis命 ...

  5. Redis 中的事务

    Redis支持简单的事务 Redis与mysql事务的对比 Mysql Redis 开启 start transaction muitl 语句 普通sql 普通命令 失败 rollback 回滚 di ...

  6. redis中的事务

    首先明白在java中线程和进程的区别: 1.什么是多线程? 是指一个应用程序同时执行多个任务,一般来说一个任务就是一个线程 ,而一个应用程序有一个以上的线程我们称之为多线程. 2.什么是进程? 进程是 ...

  7. Redis 学习(三) —— 事务、消息发布订阅

    一.Redis事务 Redis 提供的事务机制与传统的数据库事务有些不同,传统数据库事务必须维护以下特性:原子性(Atomicity), 一致性(Consistency),隔离性(Isolation) ...

  8. Redis(十一):Redis的事务功能详解

    相关命令 1. MULTI 用于标记事务块的开始.Redis会将后续的命令逐个放入队列中,然后才能使用EXEC命令原子化地执行这个命令序列. 这个命令的运行格式如下所示: MULTI 这个命令的返回值 ...

  9. 解密Redis的持久化和主从复制机制

    Redis持久化 Redis 提供了多种不同级别的持久化方式: RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot). AOF 持久化记录服务器执 ...

  10. redis高可用(主从复制)

    熟练掌握redis需要从 reids如何操作5种基本数据类型,redis如何集群,reids主从复制,redis哨兵机制redis持久化 reids主从复制 的作用可以:实现数据备份,读写分离,集群, ...

随机推荐

  1. win10中Docker安装、构建镜像、创建容器、Vscode连接实例

    Docker方便一键构建项目所需的运行环境:首先构建镜像(Image).然后镜像实例化成为容器(Container),构成项目的运行环境.最后Vscode连接容器,方便我们在本地进行开发.下面以一个简 ...

  2. Ubuntu apt-cache命令查找可用软件包

    本文GoFace给大家讲解下在Ubuntu及相同包管理的linux系统下如何查找可用软件包.在Ubuntu上大家一般使用apt-get安装软件,如果想查找某一包软件仓库中是否有,并不是使用apt-ge ...

  3. JVM 核心技术

    1.Java代码编译和执行的整个过程: 2. JVM内存管理及垃圾回收机制:  先看图, 二.Java代码编译和执行的整个过程 Java代码编译是由Java源码编译器来完成,流程图如下所示: Java ...

  4. Impala学习--代码生成(Code Generation)

    代码生成 (Code Generation) Table of Contents 1 概述 2 为何使用代码生成 3 llvm 4 Impala使用IR 5 示例 6 总结 1 概述 Cloudera ...

  5. Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Faile

    解决方法: 1.新建一个安卓应用,复制下面路径红色框的代码  去替换  导入应用中的代码,就是修改gradle版本: 2.在导入的应用中如下路径添加信息 代码: android.overridePat ...

  6. PM-企业数字化转型,数字化建设的重点

    在数字化转型深入推进的大背景下,加强数据管理,释放数据要素价值,实现企业数据价值的内部循环,形成企业数据资产,是各个企业顺应时代发展趋势,积极探索业绩新亮点的必由之路. 数字化转型四个阶段: 一. 业 ...

  7. 【Amadeus原创】docker安装TOMCAT,并运行本地代码

    1,docker 下载tomcat [root@it-1c2d ~]# docker pull tomcat ... [root@it-1c2d ~]# docker images REPOSITOR ...

  8. JEP 462 结构化并发是一个很愚蠢的提案

    https://openjdk.org/jeps/462 Motivation Developers manage complexity by breaking tasks down into mul ...

  9. 【C#】【平时作业】习题-10-委托

    什么是委托? C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针. 委托(Delegate) 是存有对某个方法的引用的一种引用类型变量.引用可在运行时被改变. 委托(Delegat ...

  10. java double转string去除科学计数法"E" 非tostring()和valueOf()

    在遇到需要将double类型转换string类型时,会出现转成科学计数法的形式,希望字符串能原样输出.直接使用会报java.lang.Double cannot be cast to java.lan ...