第四章· Redis的事務、鎖及管理命令

一.事務介紹

1.Redis的事務與關係型數據庫中的事務區別

  • 1)在MySQL中講過的事務,具備A、C、I、D四個特性
    Atomic(原子性)
    全部語句做爲一個單元所有成功執行或所有取消。
    Consistent(一致性)
    若是數據庫在事務開始時處於一致狀態,則在執行該。
事務期間將保留一致狀態。
    Isolated(隔離性)
    事務之間不相互影響。
    Durable(持久性)
    事務成功完成後,所作的全部更改都會準確地記錄在
數據庫中。所作的更改不會丟失。
  • 2)MySQL具備MVCC(多版本併發控制)的功能,這些都是根據事務的特性來完成的。git

  • 3)redis中的事務跟關係型數據庫中的事務是一個類似的概念,可是有不一樣之處。關係型數據庫事務執行失敗後面的sql語句不在執行前面的操做都會回滾,而在redis中開啓一個事務時會把全部命令都放在一個隊列中,這些命令並無真正的執行,若是有一個命令報錯,則取消這個隊列,全部命令都再也不執行。redis

  • 4)redis中開啓一個事務是使用multi,至關於begin\start transaction,exec提交事務,discard取消隊列命令(非回滾操做)。算法

空格 MySQL Redis
開啓 start transaction begin multi
語句 普通SQL 普通命令
失敗 rollback回滾 discard取消(這裏的取消不是回滾,是隊列裏的命令根本沒有執行,並非執行了以後,再撤回)
成功 commit exec

和事務相關的命令sql

1)DISCARD
取消事務,放棄執行事務塊內的全部命令。
2)EXEC
執行全部事務塊內的命令。
3)MULTI
標記一個事務塊的開始。
4)UNWATCH
取消 WATCH 命令對全部 key 的監視。
5)WATCH key [key ...]
監視一個(或多個) key ,若是在事務執行以前這個(或這些) key 被其餘命令所改動,那麼事務將被打斷。

2.事務測試

#登陸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樂觀鎖介紹

1.樂觀鎖舉例

場景:我正在買票
Ticket -1 , money -100api

而票只有1張, 若是在我multi以後,和exec以前, 票被別人買了---即ticket變成0了.
我該如何觀察這種情景,並再也不提交?緩存

1)悲觀的想法:
世界充滿危險,確定有人和我搶, 給 ticket上鎖, 只有我能操做. [悲觀鎖]安全

2)樂觀的想法:
沒有那麼人和我搶,所以,我只須要注意,
--有沒有人更改ticket的值就能夠了 [樂觀鎖]服務器

3)Redis的事務中,啓用的是樂觀鎖,只負責監測key沒有被改動.網絡

2.樂觀鎖實現

模擬買票

開啓兩個窗口實現(模擬買票)

#首先在第一個窗口設置一個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管理命令

1.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

2.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

3.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) "0"
#動態修改配置信息
127.0.0.1:6379> CONFIG SET maxmemory 60G
OK
#再次查看修改後的配置信息
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "60000000000"

4.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"

5.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)         //因而可知,每一個庫之間都是隔離的

6.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

7.monitor

開啓兩個窗口進行命令實時監控

#在第一個窗口開啓監控
127.0.0.1:6379> MONITOR
OK

#在第二個窗口輸入命令
127.0.0.1:6379> SELECT 2
OK
127.0.0.1:6379[2]> set name bgx
OK
127.0.0.1:6379[2]> info

#在第一個窗口會實時顯示執行的命令
127.0.0.1:6379> MONITOR
OK
1540392396.690268 [0 127.0.0.1:35689] "SELECT" "2"
1540392409.883011 [2 127.0.0.1:35689] "set" "name" "bgx"
1540392543.892889 [2 127.0.0.1:35689] "info"

實驗結果以下

8.shutdown

#關閉Redis服務
127.0.0.1:6379> SHUTDOWN
not connected>
相關文章
相關標籤/搜索