一.事务介绍

二.Redis乐观锁介绍

三.Redis管理命令

一.事务介绍

Redis的事务与关系型数据库中的事务区别

1)在MySQL中讲过的事务,具有A、C、I、D四个特性

  • Atomic(原子性)
    所有语句作为一个单元全部成功执行或全部取消。
  • Consistent(一致性)
    如果数据库在事务开始时处于一致状态,则在执行该
事务期间将保留一致状态。
  • Isolated(隔离性)
    事务之间不相互影响。
  • Durable(持久性)
    事务成功完成后,所做的所有更改都会准确地记录在
数据库中。所做的更改不会丢失。

2)MySQL具有MVCC(多版本并发控制)的功能,这些都是根据事务的特性来完成的。

3)redis中的事务跟关系型数据库中的事务是一个相似的概念,但是有不同之处。关系型数据库事务执行失败后面的sql语句不在执行前面的操作都会回滚,而在redis中开启一个事务时会把所有命令都放在一个队列中,这些命令并没有真正的执行,如果有一个命令报错,则取消这个队列,所有命令都不再执行。

4)redis中开启一个事务是使用multi,相当于begin\start transaction,exec提交事务,discard取消队列命令(非回滚操作)。

MySQL Redis
开启 start transaction begin multi
语句 普通SQL 普通命令
失败 rollback回滚 discard取消(这里的取消不是回滚,是队列里的命令根本没有执行,并不是执行了之后,再撤回)
成功 commit exec

和事务相关的命令
1)DISCARD
取消事务,放弃执行事务块内的所有命令。
2)EXEC
执行所有事务块内的命令。
3)MULTI
标记一个事务块的开始。
4)UNWATCH
取消 WATCH 命令对所有 key 的监视。
5)WATCH key [key ...]
监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

事务测试

#登录redis
[root@db01 ~]# redis-cli
#验证密码
127.0.0.1:6379> auth 123
OK
#不开启事务直接设置key
127.0.0.1:6379> set zls "Nice"
OK
#查看结果
127.0.0.1:6379> get zls
"Nice" #开启事务
127.0.0.1:6379> MULTI
OK
#设置一个key
127.0.0.1:6379> set bgx "low"
QUEUED
127.0.0.1:6379> set alex "Ugly"
QUEUED
#开启另一个窗口查看结果
127.0.0.1:6379> get bgx
(nil)
127.0.0.1:6379> get alex
(nil) #执行exec完成事务
127.0.0.1:6379> EXEC
1) OK
2) OK #再次查看结果
127.0.0.1:6379> get bgx
"low"
127.0.0.1:6379> get alex
"Ugly"

实验结果如下:

二.Redis乐观锁介绍


乐观锁举例

场景:我正在买票
Ticket -1 , money -100

而票只有1张, 如果在我multi之后,和exec之前, 票被别人买了---即ticket变成0了.
我该如何观察这种情景,并不再提交?

1)悲观的想法:
世界充满危险,肯定有人和我抢, 给 ticket上锁, 只有我能操作. [悲观锁]

2)乐观的想法:
没有那么人和我抢,因此,我只需要注意,
--有没有人更改ticket的值就可以了 [乐观锁]

3)Redis的事务中,启用的是乐观锁,只负责监测key没有被改动.


乐观锁实现

模拟买票

开启两个窗口实现(模拟买票)

#首先在第一个窗口设置一个key(ticket 1)
127.0.0.1:6379> set ticket 1
OK
#设置完票的数量之后观察这个票
127.0.0.1:6379> WATCH ticket
OK
#开启事务
127.0.0.1:6379> MULTI
OK
#买了票所以ticket设置为0
127.0.0.1:6379> set ticket 0
QUEUED #然后在第二个窗口观察票
127.0.0.1:6379> WATCH ticket
OK
#开启事务
127.0.0.1:6379> MULTI
OK
#同样设置ticket为0
127.0.0.1:6379> set ticket 0
QUEUED #此时如果谁先付款,也就是执行了exec另外一个窗口就操作不了这张票了
#在第二个窗口先付款(执行exec)
127.0.0.1:6379> exec
1) OK
#然后在第一个窗口再执行exec
127.0.0.1:6379> exec
(nil) //无,也就是说我们无法对这张票进行操作

实验结果如下:

三.Redis管理命令

INFO

#查看redis相关信息
127.0.0.1:6379> info
#服务端信息
# Server
#版本号
redis_version:3.2.12
#redis版本控制安全hash算法
redis_git_sha1:00000000
#redis版本控制脏数据
redis_git_dirty:0
#redis建立id
redis_build_id:3b947b91b7c31389
#运行模式:单机(如果是集群:cluster)
redis_mode:standalone
#redis所在宿主机的操作系统
os:Linux 2.6.32-431.el6.x86_64 x86_64
#架构(64位)
arch_bits:64
#redis事件循环机制
multiplexing_api:epoll
#GCC的版本
gcc_version:4.4.7
#redis进程的pid
process_id:33007
#redis服务器的随机标识符(用于sentinel和集群)
run_id:46b07234cf763cab04d1b31433b94e31b68c6e26
#redis的端口
tcp_port:6379
#redis服务器的运行时间(单位秒)
uptime_in_seconds:318283
#redis服务器的运行时间(单位天)
uptime_in_days:3
#redis内部调度(进行关闭timeout的客户端,删除过期key等等)频率,程序规定serverCron每秒运行10次
hz:10
#自增的时钟,用于LRU管理,该时钟100ms(hz=10,因此每1000ms/10=100ms执行一次定时任务)更新一次
lru_clock:13601047
#服务端运行命令路径
executable:/application/redis-3.2.12/redis-server
#配置文件路径
config_file:/etc/redis/6379/redis.conf #客户端信息
# Clients
#已连接客户端的数量(不包括通过slave的数量)
connected_clients:2
##当前连接的客户端当中,最长的输出列表,用client list命令观察omem字段最大值
client_longest_output_list:0
#当前连接的客户端当中,最大输入缓存,用client list命令观察qbuf和qbuf-free两个字段最大值
client_biggest_input_buf:0
#正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量
blocked_clients:0 #内存信息
# Memory
#由redis分配器分配的内存总量,以字节为单位
used_memory:845336
#以人类可读的格式返回redis分配的内存总量
used_memory_human:825.52K
#从操作系统的角度,返回redis已分配的内存总量(俗称常驻集大小)。这个值和top命令的输出一致
used_memory_rss:1654784
#以人类可读方式,返回redis已分配的内存总量
used_memory_rss_human:1.58M
#redis的内存消耗峰值(以字节为单位)
used_memory_peak:845336
#以人类可读的格式返回redis的内存消耗峰值
used_memory_peak_human:825.52K
#整个系统内存
total_system_memory:1028517888
#以人类可读的格式,显示整个系统内存
total_system_memory_human:980.87M
#Lua脚本存储占用的内存
used_memory_lua:37888
#以人类可读的格式,显示Lua脚本存储占用的内存
used_memory_lua_human:37.00K
#Redis实例的最大内存配置
maxmemory:0
#以人类可读的格式,显示Redis实例的最大内存配置
maxmemory_human:0B
#当达到maxmemory时的淘汰策略
maxmemory_policy:noeviction
#内存分裂比例(used_memory_rss/ used_memory)
mem_fragmentation_ratio:1.96
#内存分配器
mem_allocator:jemalloc-4.0.3 #持久化信息
# Persistence
#服务器是否正在载入持久化文件
loading:0
#离最近一次成功生成rdb文件,写入命令的个数,即有多少个写入命令没有持久化
rdb_changes_since_last_save:131
#服务器是否正在创建rdb文件
rdb_bgsave_in_progress:0
#最近一次rdb持久化保存时间
rdb_last_save_time:1540009420
#最近一次rdb持久化是否成功
rdb_last_bgsave_status:ok
#最近一次成功生成rdb文件耗时秒数
rdb_last_bgsave_time_sec:-1
#如果服务器正在创建rdb文件,那么这个域记录的就是当前的创建操作已经耗费的秒数
rdb_current_bgsave_time_sec:-1
#是否开启了aof
aof_enabled:0
#标识aof的rewrite操作是否在进行中
aof_rewrite_in_progress:0
#rewrite任务计划,当客户端发送bgrewriteaof指令,如果当前rewrite子进程正在执行,那么将客户端请求的bgrewriteaof变为计划任务,待aof子进程结束后执行rewrite
aof_rewrite_scheduled:0
#最近一次aof rewrite耗费的时长
aof_last_rewrite_time_sec:-1
#如果rewrite操作正在进行,则记录所使用的时间,单位秒
aof_current_rewrite_time_sec:-1
#上次bgrewriteaof操作的状态
aof_last_bgrewrite_status:ok
#上次aof写入状态
aof_last_write_status:ok #统计信息
# Stats
#新创建连接个数,如果新创建连接过多,过度地创建和销毁连接对性能有影响,说明短连接严重或连接池使用有问题,需调研代码的连接设置
total_connections_received:19
#redis处理的命令数
total_commands_processed:299
#redis当前的qps,redis内部较实时的每秒执行的命令数
instantaneous_ops_per_sec:0
#redis网络入口流量字节数
total_net_input_bytes:10773
#redis网络出口流量字节数
total_net_output_bytes:97146
#redis网络入口kps
instantaneous_input_kbps:0.00
#redis网络出口kps
instantaneous_output_kbps:0.00
#拒绝的连接个数,redis连接个数达到maxclients限制,拒绝新连接的个数
rejected_connections:0
#主从完全同步次数
sync_full:0
#主从完全同步成功次数
sync_partial_ok:0
#主从完全同步失败次数
sync_partial_err:0
#运行以来过期的key的数量
expired_keys:5
#过期的比率
evicted_keys:0
#命中次数
keyspace_hits:85
#没命中次数
keyspace_misses:17
#当前使用中的频道数量
pubsub_channels:0
#当前使用的模式的数量
pubsub_patterns:0
#最近一次fork操作阻塞redis进程的耗时数,单位微秒
latest_fork_usec:0
#是否已经缓存了到该地址的连接
migrate_cached_sockets:0 #主从复制信息
# Replication
#角色主库
role:master
#连接slave的个数
connected_slaves:0
#主从同步偏移量,此值如果和上面的offset相同说明主从一致没延迟,与master_replid可被用来标识主实例复制流中的位置
master_repl_offset:0
#复制积压缓冲区是否开启
repl_backlog_active:0
#复制积压缓冲大小
repl_backlog_size:1048576
#复制缓冲区里偏移量的大小
repl_backlog_first_byte_offset:0
#此值等于 master_repl_offset - repl_backlog_first_byte_offset,该值不会超过repl_backlog_size的大小
repl_backlog_histlen:0 #CPU信息
# CPU
#将所有redis主进程在内核态所占用的CPU时求和累计起来
used_cpu_sys:203.44
#将所有redis主进程在用户态所占用的CPU时求和累计起来
used_cpu_user:114.57
#将后台进程在内核态所占用的CPU时求和累计起来
used_cpu_sys_children:0.00
#将后台进程在用户态所占用的CPU时求和累计起来
used_cpu_user_children:0.00 #集群信息
# Cluster
#实例是否启用集群模式
cluster_enabled:0 #库相关统计信息
# Keyspace
#db0的key的数量,以及带有生存期的key的数,平均存活时间
db0:keys=17,expires=0,avg_ttl=0 #单独查看某一个信息(例:查看CPU信息)
127.0.0.1:6379> info cpu
# CPU
used_cpu_sys:203.45
used_cpu_user:114.58
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

client

#查看客户端连接信息(有几个会话就会看到几条信息)
127.0.0.1:6379> CLIENT LIST
id=19 addr=127.0.0.1:35687 fd=6 name= age=30474 idle=8962 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=info
id=21 addr=127.0.0.1:35689 fd=7 name= age=3 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client
#杀掉某一个会话
127.0.0.1:6379> CLIENT KILL 127.0.0.1:35687

config

重置统计状态信息
127.0.0.1:6379> CONFIG RESETSTAT
#查看所有配置信息
127.0.0.1:6379> CONFIG GET *
#查看某个配置信息
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) ""
#动态修改配置信息
127.0.0.1:6379> CONFIG SET maxmemory 60G
OK
#再次查看修改后的配置信息
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) ""

dbsize

#查看当前库内有多少个key
127.0.0.1:6379> DBSIZE
(integer) 17
#验证key的数量
127.0.0.1:6379> KEYS *
1) "lidao_fans"
2) "ticket"
3) "myhash"
4) "teacher1"
5) "name"
6) "zls_fans"
7) "bgx_fans"
8) "mykey"
9) "bgx"
10) "diffkey"
11) "alex"
12) "KEY"
13) "teacher"
14) "key3"
15) "unionkey"
16) "zls"
17) "wechat"

select

在Redis中也是有库这个概念的,不过不同于MySQL,Redis的库是默认的,并不是我们手动去创建的,在Redis中一共有16(0-15)个库。在MySQL中进入某一个库,我们需要使用use dbname,在Redis中,只需要select即可。默认情况下,我们是在0库中进行操作,每个库之间都是隔离的。

#在0库中创建一个key
127.0.0.1:6379> set name zls
OK
#查看0库中的所有key
127.0.0.1:6379> KEYS *
1) "name"
#进1库中
127.0.0.1:6379> SELECT 1
OK
#查看所有key
127.0.0.1:6379[1]> KEYS *
(empty list or set) //由此可见,每个库之间都是隔离的

flushdb、flushall

#删库跑路专用命令(删除所有库)
127.0.0.1:6379> FLUSHALL
OK
#验证一下是否真的删库了
127.0.0.1:6379> DBSIZE
(integer) 0
127.0.0.1:6379> KEYS *
(empty list or set)
#删除单个库中数据
127.0.0.1:6379> FLUSHDB
OK

shutdown

#关闭Redis服务
127.0.0.1:6379> SHUTDOWN
not connected>

第四章· Redis的事务、锁及管理命令的更多相关文章

  1. 记一个Redis分布式事务锁

    package com.mall.common; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory. ...

  2. 【JAVA今法修真】 第四章 redis特性 击穿雪崩!

    感谢这段时间大家的支持,关注我的微信号:南橘ryc ,回复云小霄,就可以获取到最新的福利靓照一张,还等什么,赶快来加入我们吧~ "明日便是决赛了,咋只会用法器没练过法术呢.". 选 ...

  3. 《JavaScript高级程序设计》——第四章 变量、作用域和内存管理

    JavaScript变量可以用保存两种类型的值:基本类型值和引用类型值.基本类型的值源自以下基本类型数据:Undefined.Null.Boolean.Number和String. 从一个变量向另一个 ...

  4. Redis之(三)管理命令

    4.1键管理 通过学习五种数据类型的操作命令,可以发现,Redis对每种数据的处理之前,都要先指定该数据的key,然后再指定对该数据进行何种操作. Redis中的key有点类似于Java中的变量名,起 ...

  5. 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存

    原文:http://blog.csdn.net/heyewu4107/article/details/71009712 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存 问 ...

  6. 利用redis实现分布式事务锁,解决高并发环境下库存扣减

    利用redis实现分布式事务锁,解决高并发环境下库存扣减   问题描述: 某电商平台,首发一款新品手机,每人限购2台,预计会有10W的并发,在该情况下,如果扣减库存,保证不会超卖 解决方案一 利用数据 ...

  7. redis事务中的WATCH命令和基于CAS的乐观锁

    转自:http://blog.sina.com.cn/s/blog_ae8441630101cgy3.html 在Redis的事务中,WATCH命令可用于提供CAS(check-and-set)功能. ...

  8. 【分布式缓存系列】Redis实现分布式锁的正确姿势

    一.前言 在我们日常工作中,除了Spring和Mybatis外,用到最多无外乎分布式缓存框架——Redis.但是很多工作很多年的朋友对Redis还处于一个最基础的使用和认识.所以我就像把自己对分布式缓 ...

  9. 【Redis】事务 (超详细)

    一.概述 二.相关命令列表 2.1 MULTI 2.2 EXEC 2.3 DISCARD 2.4 WATCH key [key ...] 2.5 UNWATCH 三.命令示例 3.1 事务被正常执行 ...

随机推荐

  1. 设计模式总结(Java)—— 观察者模式

    概述 它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应.在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多 ...

  2. Java几种常见的设计模式

    --------------------- 本文来自 旭日Follow_24 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/xuri24/article/detail ...

  3. Python全栈学习_作业集锦(持续更新)

    python基础 day1 python初识 . 计算机基础(cpu,内存,硬盘,操作系统) . Python出生于应用 . python发展史 . 编程语言分类 . python优缺点 . pyth ...

  4. CSS宽高背景介绍

    本萌新还未毕业,在一家外包公司干了一个月,因烦恼日常琐事任务,深感外包之坑,以及上班路途艰辛,特转战erp实施,继写日常随笔,望来日屌丝逆袭,走上人生巅峰. 若有错误,请前辈指点迷津,在下谢过. &l ...

  5. procemon

    全记录然后筛选子进程,保存成csv 然后用程序处理 需要去掉重复的文件

  6. (最简单)红米手机5A的USB调试模式在哪里开启的方法

    当我们使用安卓手机链接Pc的时候,或者使用的有些APP比如我们公司营销小组当使用的APP引号精灵,之前使用的老版本就需要开启usb调试模式下使用,现当新版本不需要了,如果手机没有开启usb调试模式,P ...

  7. python 实例四

    https://www.cnblogs.com/evablogs/p/6754981.html 题目:输入某年某月某日,判断这一天是这一年的第几天? 程序分析: 月份天数: 月份 天数 2 平年28天 ...

  8. 图像分析函数:skimage.measure中的label、regionprops

    算法解释详细,有算法执行过程动态GIF图的:https://blog.csdn.net/icvpr/article/details/10259577 算法文字解释的简介易懂的:https://www. ...

  9. layui中弹出层的两种表达方式

    方式一: 定义js中定义html变量 方式二: 设置div :hidden:hidden 布局 数据表格自适应大小: 代码: <style> .btn-container { margin ...

  10. #021 Java复习第一天

    上学期在慧河工作室学习简单过java到面向对象就停止了 现在有事情又要用到java发现全忘了..... 快速复习一下 网课PPT 计算机: 硬件 + 软件 主要硬件: cpu :cpu是一个计算机的运 ...