一、分布式鎖:
場景:銷售電影票(一個商品只能賣一個人)。
流程:
流程制定:看票》買票》將座位號做為key 用戶名作為value 存入redis》交錢》改各種狀態》清緩存
應該注意:1.問題:用戶還沒走到清緩存這一步就退出 會導致緩存一直存在。
解決:redis要設置過期時間 set expire 300(單位是s)。
2.問題:兩個用戶同時買票 會同時存redis 因為是同一個key所以不管是誰頂掉了誰的購買都是問題。
解決:redis有一個setnx指令 作用是:判斷這個key是否已經有值,如果沒有值,則設置這樣的key-value,並返回1,如果有值則不設置,直接返回0。
example:1:成功 0:失敗
這樣就防止后來的把先來的頂掉。
二、防止超賣
場景:5w個人一起搶10個商品。
流程:每個人讀取庫存數,且用行鎖控制。
問題:這樣會極其影象速度是不可取的,應該用redis代替行鎖:
1.創建秒殺商品A時,創建redis對象:set A 10 , 創建數據庫對象:A 10。
2.當用戶秒殺時調用 redis:INCRBY A -1 並且在redis添加購買人與購買時間:hset : A p1 1478584205( hset 商品名 購買人 購買時間)
redis知識點:incrby: 將key 中儲存的數量指定增量之值,如果key不存在初始值默認為0 .
hset: 為hash表中的字段賦值,如果hash表不存在 新建hash表並賦值,如果hash表已存在,用新值覆蓋舊值。example:
如果字段是哈希表中新建字段,並且值設置成功,返回 1 。 如果哈希表中字段已經存在且舊值已被新值覆蓋,返回 0 。
3.如果get A<0 ,則提示商品以售罄。
4.用戶付款后 扣除數據庫中秒殺庫存 並且 刪除 redis hdel A p1。
redis知識點:hdel 刪除redis hash表中一個或多個字段。example: 1:成功 0:失敗
5.跑定時看下單但未付款的人 ,超過一定時間歸還redis庫存:incrby A 1。
三、對象關系存儲
場景:客服系統會用websocket進行通訊,所以可能發生斷網,掉線的情況,但是要求客服和用戶登陸狀態是實時監控的,並且將用戶快速分配給客服。
redis主要記錄用戶信息,客服信息,兩者關系:用戶-客服 一對一 ,客服對用戶 一對多。主要使用redis的 hash結構和set結構。
流程:
場景1:客服登錄:認證客服登錄(OAuth認證)
》將客服基本信息存入redis:
hset customer1 nickname kf1 (key:customer1(客服唯一標識 ) 客服名字:kf1)
hset customer1 status 1(key:customer1(客服唯一標識 ) 登陸狀態:1)
》將登陸后的客服存入redis中:
sadd kf customer1
知識點:sadd將一個或多個成員元素加入到集合中 example:
注意:客服退出后可使用smove kf customer1,客戶掉線的話還可以恢復。
場景2:用戶登錄(通過userid登錄:用戶唯一標識)》獲取用戶信息存入redis
hset normaluser1 nickname user1(normaluser1 (用戶唯一標識 ) 用戶名字:user1)
hset normaluser1 status 1(key:customer1(客服唯一標識 ) 登陸狀態:1)
hset normaluser1 customerid customer1(存放用戶對應客服)
》存放客服對應客戶關系(一對多):
hset customer1 normaluser1 1234(關聯關系id)
場景3:業務需求:
1.查詢在線客服:smembers kf 獲得客服唯一標識再獲取具體信息
知識點:smembers 返回集合所有成員。example:
2.獲取某客服下所有用戶 hkeys coustomer1
知識點:hkeys 獲取哈希表中所有域.。example:
3.獲取用戶對應的客服 hget customer1 normaluser1
知識點:hget 返回hash表指定字段值。example:
4.客服進行轉接操作 :
hset normaluser1 customid customer2 #給用戶賦予新的客服
hdel cusomer1 normaluser1 #刪除客服1哈希表中用戶1
hset customer2 normaluser1 3412(關系標識) #賦予客服2哈希表用戶1