Java-分布式框架-redis-1

Redis核心原理

Redis的單線程和高性能
  • Redis 單線程為什么還能這么快?

因為它所有的數(shù)據(jù)都在內(nèi)存中,所有的運算都是內(nèi)存級別的運算,而且單線程避免了多線程的切換性能損耗問題。正因為 Redis 是單線程,所以要小心使用 Redis 指令,對于那些耗時的指令(比如keys),一定要謹(jǐn)慎使用,一不小心就可能會導(dǎo)致 Redis 卡頓。

  • Redis 單線程如何處理那么多的并發(fā)客戶端連接?

Redis的IO多路復(fù)用:redis利用epoll來實現(xiàn)IO多路復(fù)用,將連接信息和事件放到隊列中,依次放到文件事件分派器,事件分派器將事件分發(fā)給事件處理器。Nginx也是采用IO多路復(fù)用原理解決C10K問題

image.png

查看redis支持的最大連接數(shù),在redis.conf文件中可修改,# maxclients 10000
127.0.0.1:6379> CONFIG GET maxclients
"maxclients"
"10000"

注意:redis有著10萬QPS的性能,每秒可以處理10萬條命令。往往用戶量較高的系統(tǒng)為了解決訪問操作速度問題,而引進redis數(shù)據(jù)庫進行存儲,并且redis數(shù)據(jù)庫存儲的數(shù)據(jù)量往往占比會很高,比如70%。

其他高級命令
  • keys:全量遍歷鍵,用來列出所有滿足特定正則字符串規(guī)則的key,當(dāng)redis數(shù)據(jù)量比較大時,性能比較差,要避免使用。keys的使用有精準(zhǔn)查找、全局查找、模糊查找。


    image.png
  • scan:漸進式遍歷鍵

SCAN cursor [MATCH pattern] [COUNT count] 

scan 參數(shù)提供了三個參數(shù),第一個是 cursor 整數(shù)值,第二個是 key 的正則模式,第三個是一次遍歷的key的數(shù)量,并不是符合條件的結(jié)果數(shù)量。第一次遍歷時,cursor 值為 0,然后將返回結(jié)果中第一個整數(shù)值作為下一次遍歷的 cursor。一直遍歷到返回的 cursor 值為 0 時結(jié)束。

  • Info:查看redis服務(wù)運行信息,分為 9 大塊,每個塊都有非常多的參數(shù),這 9 個塊分別是:
    Server 服務(wù)器運行的環(huán)境參數(shù)
    Clients 客戶端相關(guān)信息
    Memory 服務(wù)器運行內(nèi)存統(tǒng)計數(shù)據(jù)
    Persistence 持久化信息
    Stats 通用統(tǒng)計數(shù)據(jù)
    Replication 主從復(fù)制相關(guān)信息
    CPU CPU 使用情況
    Cluster 集群信息
    KeySpace 鍵值對統(tǒng)計數(shù)量信息

Redis核心數(shù)據(jù)結(jié)構(gòu)

概述

Redis核心數(shù)據(jù)主要包括字符串string、哈希hash、列表list、集合set、有序集合zset,也是經(jīng)常使用的。


image.png
String結(jié)構(gòu)
  • 單值緩存
set key value
get key
  • 對象緩存
    對象的緩存有2種方式,一種是把對象轉(zhuǎn)為json字符串,以字符串的形式把對象存到redis;另一種方式批量把對象的屬性存到redis。相比下,第二種方式占用的內(nèi)存要少,同時在修改上第二種可以直接到redis上改,不需要先讀取,再修改,后更新。
1. set user:id value(json格式數(shù)據(jù))
   get user:id
2. mset user:id:name value_name user:id:age value_age
   mget user:id:name user:id:age
  • 分布式鎖
    分布式鎖的實現(xiàn)可以使用SETNX命令實現(xiàn),SETNX操作成功表示獲取鎖成功,反之獲取鎖失敗,DEL命令刪除對應(yīng)的key表示釋放鎖,其中也需要設(shè)置獲取鎖操作的超時時間,以防出現(xiàn)死鎖。
SETNX  product:10001  true      //返回1代表獲取鎖成功
SETNX  product:10001  true      //返回0代表獲取鎖失敗
。。。執(zhí)行業(yè)務(wù)操作
DEL  product:10001              //執(zhí)行完業(yè)務(wù)釋放鎖
SET product:10001 true  ex  10  nx  //防止程序意外終止導(dǎo)致死鎖
  • 計數(shù)器
    redis它是單線程執(zhí)行的,就算是多線程并發(fā)對redis進行操作,redis這邊都會把操作請求進行排隊串行化,再逐一進行處理,說白了redis下就只有一個線程在執(zhí)行。
INCR article:readcount:{文章id}   
GET article:readcount:{文章id} 
  • Web集群session共享
    spring session + redis實現(xiàn)session共享

  • 分布式系統(tǒng)全局序列號
    INCRBY orderId 1000 //redis批量生成序列號提升性能

Hash結(jié)構(gòu)

List常用命令如下:

HSET  key  field  value             //存儲一個哈希表key的鍵值
HSETNX  key  field  value       //存儲一個不存在的哈希表key的鍵值
HMSET  key  field  value [field value ...]  //在一個哈希表key中存儲多個鍵值對
HGET  key  field                //獲取哈希表key對應(yīng)的field鍵值
HMGET  key  field  [field ...]      //批量獲取哈希表key中多個field鍵值
HDEL  key  field  [field ...]       //刪除哈希表key中的field鍵值
HLEN  key               //返回哈希表key中field的數(shù)量
HGETALL  key                //返回哈希表key中所有的鍵值
HINCRBY  key  field  increment      //為哈希表key中field鍵的值加上增量increment
  • 對象緩存
    對象緩存的使用用hash結(jié)構(gòu)相比string結(jié)構(gòu)的第二種來說,更加合理,更加方便。
    優(yōu)點
    1)同類數(shù)據(jù)歸類整合儲存,方便數(shù)據(jù)管理
    2)相比string操作消耗內(nèi)存與cpu更小
    3)相比string儲存更節(jié)省空間
    缺點
    1)過期功能不能使用在field上,只能用在key上
    2)Redis集群架構(gòu)下不適合大規(guī)模使用
HMSET  user  {userId}:name  value_name {userId}:age  value_age
HMSET  user  1:name  xiaoming 1:age  18
HMGET  user  1:name  1:age
  • 應(yīng)用場景

電商購物車
1)以用戶id為key
2)商品id為field
3)商品數(shù)量為value

image.png

購物車操作

添加商品 hset cart:1001 10088 1
增加數(shù)量 hincrby cart:1001 10088 1
商品總數(shù) hlen cart:1001
刪除商品 hdel cart:1001 10088
獲取購物車所有商品 hgetall cart:1001
List結(jié)構(gòu)

List常用命令如下:

LPUSH  key  value [value ...]       //將一個或多個值value插入到key列表的表頭(最左邊)
RPUSH  key  value [value ...]       //將一個或多個值value插入到key列表的表尾(最右邊)
LPOP  key                           //移除并返回key列表的頭元素
RPOP  key                           //移除并返回key列表的尾元素
LRANGE  key  start  stop            //返回列表key中指定區(qū)間內(nèi)的元素,區(qū)間以偏移量start和stop指定
BLPOP  key  [key ...]  timeout      //從key列表表頭彈出一個元素,若列表中沒有元素,阻塞等待      timeout秒,如果timeout=0,一直阻塞等待
BRPOP  key  [key ...]  timeout      //從key列表表尾彈出一個元素,若列表中沒有元素,阻塞等待      timeout秒,如果timeout=0,一直阻塞等待
image.png
  • 常用數(shù)據(jù)結(jié)構(gòu)

Stack(棧) = LPUSH + LPOP -->FILO
Queue(隊列)= LPUSH + RPOP -->FIFO
Blocking MQ(阻塞隊列)= LPUSH + BRPOP -->FIFO

  • 應(yīng)用場景
    公眾號頁面消息展示。

1)關(guān)注的UP主1發(fā)公眾號,消息ID為10018
LPUSH msg:{我的ID} 10018
2)關(guān)注的UP主2發(fā)公眾號,消息ID為10086
LPUSH msg:{我的ID} 10086
3)查看最新公眾號消息 //前5條
LRANGE msg:{我的ID} 0 5

Set結(jié)構(gòu)
  • Set常用操作
SADD  key  member  [member ...]         //往集合key中存入元素,元素存在則忽略,若key不存在則新建
SREM  key  member  [member ...]         //從集合key中刪除元素
SMEMBERS  key                           //獲取集合key中所有元素
SCARD  key                              //獲取集合key的元素個數(shù)
SISMEMBER  key  member                  //判斷member元素是否存在于集合key中
SRANDMEMBER  key  [count]               //從集合key中選出count個元素,元素不從key中刪除
SPOP  key  [count]                      //從集合key中選出count個元素,元素從key中刪除
  • Set運算操作
SINTER  key  [key ...]              //交集運算
SINTERSTORE  destination  key  [key ..]     //將交集結(jié)果存入新集合destination中
SUNION  key  [key ..]               //并集運算
SUNIONSTORE  destination  key  [key ...]        //將并集結(jié)果存入新集合destination中
SDIFF  key  [key ...]               //差集運算
SDIFFSTORE  destination  key  [key ...]     //將差集結(jié)果存入新集合destination中
  • 應(yīng)用場景

抽獎活動,隨機抽取1位一等獎,2位二等獎,3位三等獎,保證中獎人數(shù)不重復(fù)。

SPOP key 1
SPOP key 2
SPOP key 3

微信微博點贊,收藏,標(biāo)簽

1) 點贊
SADD  like:{消息ID}  {用戶ID}
2) 取消點贊
SREM like:{消息ID}  {用戶ID}
3) 檢查用戶是否點過贊
SISMEMBER  like:{消息ID}  {用戶ID}
4) 獲取點贊的用戶列表
SMEMBERS like:{消息ID}
5) 獲取點贊用戶數(shù) 
SCARD like:{消息ID}

集合操作實現(xiàn)微博微信關(guān)注模型

1) A關(guān)注的人: 
ASet-> {B, C, D}
2) B關(guān)注的人:
 BSet--> {A, C, D, E}
3) C關(guān)注的人: 
CSet-> {A, B, E, D, F)
4) A和B共同關(guān)注: 
SINTER ASet BSet--> {C, D}
5) A關(guān)注的人也關(guān)注他(B): 
SISMEMBER CSet B 
SISMEMBER DSet B
6) A可能認(rèn)識的人: 
SDIFF BSet ASet->(A, E}

集合操作實現(xiàn)電商商品篩選

SADD  brand:huawei  P30
SADD  brand:xiaomi  mi-6X
SADD  brand:iPhone iphone8
SADD os:android  P30  mi-6X
SADD cpu:brand:intel  P30  mi-6X
SADD ram:8G  P30  mi-6X  iphone8
//交集操作獲取結(jié)果
SINTER  os:android  cpu:brand:intel  ram:8G  {P30,mi-6X}

注意:操作在redis中為微秒級別,這樣的操作在高并發(fā)中在redis很快,在傳統(tǒng)數(shù)據(jù)庫中很慢。

ZSet結(jié)構(gòu)
  • ZSet常用操作
ZADD key score member [[score member]…] //往有序集合key中加入帶分值元素
ZREM key member [member …]      //從有序集合key中刪除元素
ZSCORE key member           //返回有序集合key中元素member的分值
ZINCRBY key increment member        //為有序集合key中元素member的分值加上increment 
ZCARD key               //返回有序集合key中元素個數(shù)
ZRANGE key start stop [WITHSCORES]  //正序獲取有序集合key從start下標(biāo)到stop下標(biāo)的元素
ZREVRANGE key start stop [WITHSCORES]   //倒序獲取有序集合key從start下標(biāo)到stop下標(biāo)的元素
  • Zset集合操作
ZUNIONSTORE destkey numkeys key [key ...]   //并集計算
ZINTERSTORE destkey numkeys key [key …] //交集計算
image.png
  • 應(yīng)用場景

Zset集合操作實現(xiàn)新聞排行榜

1)點擊新聞
ZINCRBY  hotNews:20190819  1  守護香港
2)展示當(dāng)日排行前十
ZREVRANGE  hotNews:20190819  0  10  WITHSCORES 
3)七日搜索榜單計算
ZUNIONSTORE  hotNews:20190813-20190819  7 
hotNews:20190813  hotNews:20190814... hotNews:20190819
4)展示七日排行前十
ZREVRANGE hotNews:20190813-20190819  0  10  WITHSCORES
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 今天為大家分享一個系列的教程Redis高級應(yīng)用實戰(zhàn)分布式緩存,今天文章內(nèi)容概要:1、那么分布式緩存為什么要用Red...
    艾編程閱讀 369評論 0 1
  • 為什么要用緩存? 高性能 假設(shè)這么個場景,你有個操作,一個請求過來,吭哧吭哧你各種亂七八糟操作mysql,半天查出...
    _云起閱讀 7,500評論 1 50
  • 表情是什么,我認(rèn)為表情就是表現(xiàn)出來的情緒。表情可以傳達很多信息。高興了當(dāng)然就笑了,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 129,633評論 2 7
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險厭惡者,不喜歡去冒險,但是人生放棄了冒險,也就放棄了無數(shù)的可能。 ...
    yichen大刀閱讀 7,791評論 0 4

友情鏈接更多精彩內(nèi)容