技能儲備

JAVA基礎

JVM

設計模式

技術棧

Redis(Remote Dictionary Server(遠程數據服務))緩存

Redis是基於內存的高速緩存key-value數據庫(C語言開發)

優點

1.基於內存讀寫速度快,可以支持高性能的業務場景

2.支持豐富的數據結構(String,hash,set,list,sort)

3.QPS可以達10萬+

缺點

  1. 數據不一致
  2. 緩存雪崩
  3. 緩存穿透
  4. 緩存併發
  5. 數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫

數據不一致問題(mysql+redis)

業界方案:監聽mysql的binlog日誌,異步淘汰緩存

緩存雪崩(大量緩存同時失效,導致直接查DB,導致DB壓力太大奔潰)

業界方案:將熱點數據設置不同的過期時間,以防止同時查詢熱點數據給數據庫帶來壓力

緩存穿透(針對用戶惡意攻擊)

在查詢緩存沒有值,再查詢mysql也沒有值時,會將此key的value設置爲null,並添加六十秒過期時間

業界方案:布隆過濾器(存在誤算率,隨着存入的元素數量增加,誤算率也隨着增加)

布隆過濾器的思想:核心是實現了一個超大的位數組和幾個哈希函數,每一個元素,都調用這幾個哈希函數算出哈希值,並落到這個數組中,隨着元素的增加,哈希值的相似度就會升高,誤判率就會出現

 

Redis熱點key的尋找方案

redis於4.0.3版本開始正式支持基於LFU的熱點key發現機制。

Least Frequently Used——簡稱LFU,意爲最不經常使用,是redis4.0新增的一類內存逐出策略,從LFU的字面意思我們很容易聯想到key的訪問頻率,並對訪問頻率進行了統計

可以對概率因子和衰減因子進行配置,推薦使用redis的默認值即可:

lfu-log-factor 10lfu-decay-time 1要注意需要先把內存逐出策略設置爲allkeys-lfu或者volatile-lfu,否則會返回錯誤

redis 4.0.3同時也提供了redis-cli的熱點key發現功能,執行redis-cli時加上–hotkeys選項即可,示例如下:$./redis-cli –hotkeys 排在前面就是熱點key

Redis和Memcache對比

 

Redis

Memcache

數據結構

多種數據結構:String,hash,set,list,sort

Key-value

集羣模式

Redis自帶(redis cluster)

客戶端自己實現

線程模式

單線程(小數據量性能好,可以持久化)

多線程(大數據量100M性能好,不能持久化)

 


 

 

 

 

 

 

 

 

 

 

MQ(Message Queue)消息隊列

MQ:是一種應用程序對應用程序傳遞消息的中間件,是通過讀寫出入隊列來通信。

三種通訊模式 1.點對點,2.多點廣播,3.發佈和訂閱(一般用這個)

優點

1.異步:執行失敗重試,提高接口的性能(失效策略;數據回補)

2.解耦:利用MQ降低系統的耦合性(系統重構)

3.削峯:將一些無需及時返回且耗時的操作提取出來,進行異步處理,從而節省服務器的響應時間來提高系統的吞吐量(秒殺,公司的活動:搶金幣)

缺點

1.MQ一旦掛了,整個系統就奔潰了(高可用)

2.系統的複雜度提高(消息堆積)

3.數據不一致(消息重複,消息順序,消息丟了)

如何選型:RabbitMQ,RocketMQ,Kafka

Kafka是主要用於配合大數據類的系統來進行實時數據計算、日誌採集等場景(主要支持簡單的MQ功能)

我們一般在RabbitMQ和RocketMQ中間來選擇

選擇RocketMQ的理由(阿里出品):

1.topic可以達到幾百,幾千個的級別,吞吐量會有較小幅度的下降(RabbitMQ會大幅下降)

2.分佈式集羣,每個部分都可以水平擴展(RabbitMQ主從集羣)

3.java開發(RabbitMQ用erlang語言開發)

4.吞吐量是10萬級(RabbitMQ是萬級)

缺點:

1.延時毫秒級(RabbitMQ是微秒級)

2.社區活躍度一般(RabbitMQ比較好版本迭代特別快)

 

MQ的高可用

RabbitMQ是鏡像集羣模式(主從)

Kafka是分佈式集羣(副本集,HA),每個節點都有一個replicate備份。讀寫都在leader節點

RocketMQ是分佈式集羣如下

Name Server:主要提供輕量級查找和路由服務(保存了其它三部分的信息)(各個節點之間不通信)

Broker Cluster:輕量的topic和queue機制(消息的存儲,支持push和pull)

Product Cluster:分佈式的producers通過負載均衡模型向broker發送消息

Consumer Cluster:支持push,pull,支持集羣消費與消息廣播同時提供實時訂閱

 

 

MQ的消息冪等性(不重複)

造成的原因:1.系統重啓  2.網絡異常  3.消費失敗

解決方案

  1. 消息的唯一標識存入redis中並進行判斷
  2. 數據庫的存儲判斷

MQ丟消息

  1. producter:發送消息狀態超時或者失敗,則會觸發默認的2次重試(支持日誌的索引查找)
  2. broker:是一主多從的節點,同時支持同步和異步刷盤的策略,保證消息落到本地內存中,消息也支持持久化到commitlog裏面,即使宕機,未消費的消息也可以加載出來
  3. consumer:確保拉取到的消息成功消費,consumer自身維護了一個持久化的offset,消費成功後纔會更新自己的offset,offset會持久化到本地,即使consumer掛掉重啓之後可以繼續拉取offset之前的消息到本地

MQ消息的積壓

策略:超出了buffer,也可以丟棄,然後再從CommitLog中補數據

打開rocketmq的控制檯查看是歷史消費記錄,如果是消息寫入速度大於消息的消費速度,調整業務代碼或對消費者進行擴容

Consumer消費消息出現問題,只能操作臨時緊急擴容了,具體操作步驟和思路如下:

1)先修復consumer的問題,確保其恢復消費速度,然後將現有cnosumer都停掉

2)新建一個topic,partition是原來的10倍,臨時建立好原先10倍或者20倍的queue數量

3)然後寫一個臨時的分發數據的consumer程序,這個程序部署上去消費積壓的數據,消費之後不做耗時的處理,直接均勻輪詢寫入臨時建立好的10倍數量的queue

4)接着臨時徵用10倍的機器來部署consumer,每一批consumer消費一個臨時queue的數據

5)這種做法相當於是臨時將queue資源和consumer資源擴大10倍,以正常的10倍速度來消費數據

6)等快速消費完積壓數據之後,得恢復原先部署架構,重新用原先的consumer機器來消費消息

MQ消息的順序

避開這種使用場景

數據庫

Mysql事務默認(可重複讀)

事務隔離級別

髒讀

不可重複讀

幻讀

讀未提交(read-uncommitted

不可重複讀(read-committed

可重複讀(repeatable-read

串行化(serializable

 髒讀:一個事務讀到另一個事務未提交的更新數據

幻讀:已提交的插入數據

 

 

 

 

mysql默認的事務隔離級別爲repeatable-read

 

網絡

URL解析統一資源定位符 (Uniform Resource Locator, URL) 

調用鏈路

http://www.baidu.com(scheme:通信協議, host:主機, port:端口號)

 

DNS解析(DNS緩存)

 

TCP連接

 

發送http請求

 

服務器處理請求並返回http報文

 

瀏覽器解析渲染頁面

 

連接結束

 

 

 

 

 

 

 

 

思考

秒殺設計思路

用戶量不大的策略

隊列+redis全局計數器即可

用戶量大的策略(柔性服務策略)

  1. 前端處理95%的請求直接返回已經售光(前端隨機數,矩陣,離散等概率算法)
  2. 全局計數處理
  3. 降級跳過非關鍵邏輯
  4. 中間錯誤異步修復
  5. 業務流程上可以通過:搶購預約碼

 

有損服務的策略(列表頁)

第一種策略

         列表頁分爲三塊,同時發起三個異步請求後端進行處理

 

第二種策略

         A:搜索篩選項時,比如搜索海淀-知春路的帖子,只出海澱的帖子(維度高一些)

         B:第三塊是廣告頁可以選擇不展示

         C:列表頁中的數據可以繼續簡化(簡化埋點,日誌,廣告等業務數據)

         D:篩選項可以進行15分鐘一次的緩存刷新

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章