1. 程式人生 > >Redis的事務、鎖及管理命令

Redis的事務、鎖及管理命令

1.事物介紹

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取消佇列命令(非回滾操作)。

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

### 事務測試

 

#登入redis
[[email protected]

~]# 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"

 2.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) //無,也就是說我們無法對這張票進行操作

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

 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

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"

shutdown

#關閉Redis服務

127.0.0.1:6379> SHUTDOWN

not connected>