1、簡單介紹一下redis,有什麼特點?
官網介紹:
Redis 是一個開源(BSD許可)的,內存中的數據結構存儲系統,它可以用作資料庫、緩存和消息中間件。它支持多種類型的數據結構,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 與範圍查詢, bitmaps, hyperloglogs 和 地理空間(geospatial) 索引半徑查詢。Redis 內置了 複製(replication),LUA腳本(Lua scripting), LRU驅動事件(LRU eviction),事務(transactions) 和不同級別的 磁碟持久化(persistence), 並通過 Redis哨兵(Sentinel)和自動 分區(Cluster)提供高可用性(high availability)。
特點:
(1)讀寫性能高
(2)數據類型豐富
(3)可持久化
(4)單線程,多路復用
2、Redis支持哪些數據類型?底層存儲結構分別是什麼?
set/get/incr/decr/incrby/decrby3. 底層存儲結構:簡單動態字符串(SDS: simple dynamic string)struct sdshdr{ int len; int free; char buf[];}lpush/lpop/rpush/rpop/llen1. 列表類型存儲的值為字符串類型,可以實現簡單消息隊列功能2. 每個list可以存儲 2^32 -1 個值(40多億)3. 可以從隊列頭部(lpush)或尾部插入(rpush)typedef struct listNode{ struct listNode *prev; struct listNode *next; void *value; }listNodesadd/scard/smembers/sismember/srem3. 每個set 可以存儲 2^32 -1 個值(40多億)4. 是通過hash實現的,新增/刪除/查找的複雜度均為O(1)5. 底層存儲結構:intset(整數集合) 或 hashtable(字典的值為null)6. 當同時滿足以下兩個條件時才使用intset存儲,否則使用hashtable存儲:typedef struct intset{ uint32_t encoding; uint32_t length; int8_t contents[];}intset;(4)Hash
2. 每個 hash 可以存儲 2^32 -1 鍵值對(40多億)typedef struct dictht{ dictEntry **table; unsigned long size; unsigned long sizemask; unsigned long used;}dicthtzadd/zcard/zrange/zrangebyscore1. 存儲的是字符串類型,每一個元素關聯一個double類型的分數2. 每個zset 可以存儲 2^32 -1 個值(40多億)4. 底層存儲的結構可以是ziplist或skiplist5. 當同時滿足以下兩個條件時才使用ziplist存儲,否則使用skiplist存儲typedef struct zskiplistNode { struct zskiplistLevel{ struct zskiplistNode *forward; unsigned int span; }level[]; struct zskiplistNode *backward; double score; robj *obj; } zskiplistNode
typedef struct zskiplist{ structz skiplistNode *header, *tail; unsigned long length; int level; }zskiplist;3、Redis有哪些持久化方式?
(1)在指定的觸發機制下以快照的方式將內存中的數據寫入磁碟(5)有三種觸發快照的機制:save(阻塞)、bgsave(後臺非阻塞)、自動化(1)存儲文件緊湊,體積小,傳輸速度快,適合災難恢復
(1)快照過程中,無法保存所有的數據,數據量越大時,快照需要的時間越多,期間遺漏的數據越多(1)記錄每一條修改數據的指令,包括:新增、修改、刪除
(2)通過配置「appendonly yes」打開AOF功能(1)比RDB可靠,秒級數據丟失(取決於設置fsync策略)(3)數據恢復可控性高,如:通過刪除末尾部分指令進行回退
(3)由於需要頻繁的將命令刷新到文件中,對性能影響比RDB大4、什麼是緩存穿透、緩存擊穿、緩存雪崩?各有什麼解決方法?
(1)緩存穿透
待查詢的key不存在,攻擊者可以構造一些不存在的特殊數據,發起大量請求落到資料庫中,導致資料庫壓力過大甚至掛掉。
解決方法:
(1)異常數據攔截:通過規則攔截不可能存在資料庫中的數據(如:手機號,email 都有特殊格式)。
(2)設置數據存在標識:如:使用布隆過濾器將存在的key緩存起來,可以過濾掉大部分不存在的key。
(3)緩存不存在的key:構造一個特殊的值緩存不存在的key,緩存時間設定短一些。
(2)緩存擊穿
查詢的key存在資料庫中,某一個時間點緩存超時,同時有大量該key的查詢,都落到數據中,導致資料庫壓力過大甚至掛掉。
解決方法:
當緩存中沒有查到該key,準備去查資料庫之前,進行加鎖,即每個key最多只允許一個線程去查資料庫,從而降低資料庫的壓力。
(3)緩存雪崩
某個時間點,大量key超時,這些key的查詢都落到資料庫,導致資料庫壓力過大甚至掛掉。
解決方法:
key的超時時間設置分散一點,可以設置成一個區間的隨機值。
5、Redis有哪些應用場景?
(1)緩存會話
(2)秒殺活動
(3)排行榜
(4)分布式鎖
(5)計數問題
(6)消息發布與訂閱