5萬人關注的大資料成神之路,不來了解一下嗎?
5萬人關注的大資料成神之路,真的不來了解一下嗎?
5萬人關注的大資料成神之路,确定真的不來了解一下嗎?
歡迎您關注《大資料成神之路》

1.string
這是最基本的類型了,就是普通的set和get,做簡單的kv緩存。
2.hash
這個是類似map的一種結構,這個一般就是可以将結構化的資料,比如一個對象(前提是這個對象沒嵌套其他的對象)給緩存在redis裡,然後每次讀寫緩存的時候,可以就操作hash裡的某個字段。
key=150
value={
“id”: 150,
“name”: “zhangsan”,
“age”: 20
}
複制
hash類的資料結構,主要是用來存放一些對象,把一些簡單的對象給緩存起來,後續操作的時候,你可以直接僅僅修改這個對象中的某個字段的值
value={
“id”: 150,
“name”: “zhangsan”,
“age”: 21
}
複制
3.list
有序清單,這個是可以做很多不同操作的
比如:微網誌,某個大v的粉絲,就可以以list的格式放在redis裡去緩存
key=某大v
value=[zhangsan, lisi, wangwu]
複制
比如:可以通過list存儲一些清單型的資料結構,類似粉絲清單了、文章的評論清單了之類的東西
比如:可以通過lrange指令,就是從某個元素開始讀取多少個元素,可以基于list實作分頁查詢,這個很棒的一個功能,基于redis實作簡單的高性能分頁,可以做類似微網誌那種下拉不斷分頁的東西,性能高,就一頁一頁走
比如:可以搞個簡單的消息隊列,從list頭怼進去,從list尾巴那裡弄出來
4.set
無序集合,自動去重
直接基于set将系統裡需要去重的資料扔進去,自動就給去重了,如果你需要對一些資料進行快速的全局去重,你當然也可以基于jvm記憶體裡的HashSet進行去重,但是如果你的某個系統部署在多台機器上呢?
得基于redis進行全局的set去重
可以基于set玩兒交集、并集、差集的操作,比如交集吧,可以把兩個人的粉絲清單整一個交集,看看倆人的共同好友是誰?對吧
把兩個大v的粉絲都放在兩個set中,對兩個set做交集
5.sorted set
排序的set,去重但是可以排序,寫進去的時候給一個分數,自動根據分數排序,這個可以玩兒很多的花樣,最大的特點是有個分數可以自定義排序規則
比如說你要是想根據時間對資料排序,那麼可以寫入進去的時候用某個時間作為分數,人家自動給你按照時間排序了
排行榜:将每個使用者以及其對應的什麼分數寫入進去,zadd board score username,接着zrevrange board 0 99,就可以擷取排名前100的使用者;zrank board username,可以看到使用者在排行榜裡的排名
zadd board 85 zhangsan
zadd board 72 wangwu
zadd board 96 lisi
zadd board 62 zhaoliu
96 lisi
85 zhangsan
72 wangwu
62 zhaoliu
zrevrange board 0 3
擷取排名前3的使用者
96 lisi
85 zhangsan
72 wangwu
zrank board zhaoliu
4
複制
6. 資料為什麼會過期?
首先,要明白redis是用來做資料緩存的,不是用來做資料存儲的(當然也可以當資料庫用),是以資料時候過期的,過期的資料就不見了,過期主要有兩種情況,
①在設定緩存資料時制定了過期時間,這樣到了過期時間資料就不見了。
②redis的資料是存放在記憶體中的,而記憶體是有限的,是不可能放過多資料的,比如隻有10G的記憶體,想要向裡面放入20G的資料,那麼就注定會有10G的資料會丢失。
7. redis的過期政策是什麼樣的?
redis采用了 “定期删除+惰性删除” 的過期政策。
①定期删除
原理:定期删除指的是redis預設每隔100ms就随機抽取一些設定了過期時間的key,檢測這些key是否過期,如果過期了就将其删掉。
為什麼會選擇一部分,而不是全部:因為如果這是redis裡面有大量的key都設定了過期時間,那麼如果全部去檢測一遍,CPU負載就會很高,會浪費大量的時間在檢測上面,甚至直接導緻redis挂掉。所有隻會抽取一部分而不會全部檢查。
出現問題:這樣的話就會出現大量的已經過期的key并沒有被删除,這就是 為什麼有時候大量的key明明已經過了失效時間,但是redis的記憶體還是被大量占用的原因 ,為了解決這個問題,就需要 惰性删除 這個政策了。
②惰性删除
原理:惰性删除不在是redis去主動删除,而是在你要擷取某個key 的時候,redis會先去檢測一下這個key是否已經過期,如果沒有過期則傳回給你,如果已經過期了,那麼redis會删除這個key,不會傳回給你。
這樣兩種政策就保證了 過期的key最終一定會被删除掉 ,但是這隻是保證了最終一定會被删除,要是定時删除漏掉了大量過期的key,而且我們也沒有及時的去通路這些key,那麼這些key不就不會被删除了嗎?不就會一直占着我們的記憶體嗎?這樣不還是會導緻redis記憶體耗盡嗎?
由于存在這樣的問題,是以redis引入了 記憶體淘汰機制 來解決。
8.記憶體淘汰機制
記憶體淘汰機制就保證了在redis的記憶體占用過多的時候,去進行記憶體淘汰,也就是删除一部分key,保證redis的記憶體占用率不會過高,那麼它會删除那些key呢?
redis提供了6中記憶體淘汰政策,我們可以去進行選擇,六中政策如下:
①noeviction:當記憶體不足以容納新寫入資料時,新寫入操作會報錯,無法寫入新資料,一般不采用。
②allkeys-lru:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的key,這個是最常用的。
③allkeys-random:當記憶體不足以容納新寫入的資料時,在鍵空間中,随機移除key,一般也不使用。
④volatile-lru:volatile-lru:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最近最少使用的key(這個一般不太合适) 。
⑤volatile-random:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,随機移除某個key 。
⑥volatile-ttl:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的key優先移除。
9.手寫一個LRU算法
//基于JavaLinkedHashMap實作
public class LRUCache<K,V> extends LinkedHashMap<K,V>{
private final int CACHE_SIZE;
//儲存傳遞進來的最大資料量
public LRUCache(int cacheSize){
//設定hashmap的初始大小,同時最後一個true指的是讓linkedhashmap按照通路順序來進行排序,
//最近通路的放在頭,最老通路的放在尾
super((int)Math.ceil(cacheSize/0.75)+1,0.75f,true);
CACHE_SIZE = CacheSize;
}
@Override
protected boolean removeEldestEntry(Map.Entry eldest){
//當map中的資料量大于指定的緩存個數的時候,就自動删除最老的資料。
return size() > CACHE_SIZE;
}
}
複制
— THE END —