国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Redis 應用案例 - 在問題中不斷成長

2019-11-09 13:35:39
字體:
來源:轉載
供稿:網友

背景

產品類型:酒店搜索

技術選型:前端 php + 后端 java,都會用到 Redis

Redis 使用場景:緩存、數據持久化前的臨時存儲

2010年開始應用 Redis,PHP 對其操作時使用的是 PRedis 這個客戶端庫

2013年改用了 phpredis 作為客戶端庫

2014年開始出現問題

問題描述

用戶量快速增長,訪問量在短時間內翻倍,由于前期容量規劃做得比較好,硬件資源可以支撐,可是軟件系統方面出現了大問題:

40% 的請求都會返回 HTTP 500: Internal Server Error

通過查看日志,發現錯誤是在 PHP <-> Redis 的連接處理上

調試處理

第1次

剛開始時并沒有找到根本原因,只能嘗試各種與錯誤相關的辦法,例如:

增加 PHP 連接數,并把超時時間從 500ms 增加到 2.5s

禁止掉 PHP 設置中的 default_socket_timeout

在主機系統中禁止掉 SYN cookies

檢查 Redis 和 Webservers 的文件描述符數量

增加主機系統的 mbuffer

調整 TCP backlog 數量

……

嘗試了很多方法,但全部無效

第2次

想在預發布環境中重現這個問題,可惜,還是沒成功,應為流量不夠大,無法復現

第3次

會不會是代碼中沒有關閉 Redis 連接呢?

正常來講,PHP在執行結束時會自動關閉資源連接,但老版本中會有內存泄漏的問題,保險起見,把代碼都修改一遍,手動關閉連接

結果還是無效

第4次

懷疑目標:phpredis 這個客戶端庫

做 A/B 測試,替換回 predis 這個庫,部署到數據中心中 20% 的用戶量上

得益于良好的代碼結構,替換工作很快完成

可結果依舊是無效,但也有好的一面,可以證明 phpredis 沒問題嘛

第5次

查看了一下 Redis 的版本,是 v2.6,當時最新版本是 v2.8.9

升級 Redis 試一下吧,升完后還是不行

沒事兒,要保持樂觀,這不順便把 Redis 版本升為最新的了

第6次

通過查找大量文檔,在官方文檔中發現了一個調試好方法 Redis Software Watchdog,打開后執行:

$ redis-cli --latency -p 6380 -h 1.2.3.4min: 0, max: 463, avg: 2.03 (19443 samples)

查看 Redis 日志:

...[20398] 22 May 09:20:55.351 * 10000 changes in 60 seconds. Saving...[20398] 22 May 09:20:55.759 * Background saving started by pid 41941[41941] 22 May 09:22:48.197 * DB saved on disk[20398] 22 May 09:22:49.321 * Background saving terminated with success[20398] 22 May 09:25:23.299 * 10000 changes in 60 seconds. Saving...[20398] 22 May 09:25:23.644 * Background saving started by pid 42027...

發現了問題:

每隔幾分鐘就向硬盤保存一次數據,fork 一個后臺存儲進行為什么需要大概 400ms(通過上面日志的第1條和第2條的時間可以看出來)

到這兒,終于找到問題的根源了,因為 Redis 實例中有大量的數據,導致每次持久化操作 fork 后臺進程時非常耗時,并且在他們的業務中經常修改key,又導致了頻繁觸發持久化,也就經常產生對 Redis 的阻塞

處理辦法:使用單獨的 slave 來做持久化

這個 slave 不處理真實的流量請求,唯一的作用就是處理持久化,把之前 Redis 實例上的持久化操作轉移到這個 slave 上

效果非常明顯,問題基本解決,但有的時候還是會報錯

第7次

排查可能阻塞 Redis 的慢查詢,發現有地方使用了 keys *

因為 Redis 中的數據越來越多,這個命令自然會產生嚴重阻塞

可以使用 scan 進行替換

第8次

經過前面的調整,問題已經解決,隨后的幾個月,即使流量在不斷增長,也都抗住了

但他們意識到了新的問題:

現在的方式是,來一個請求就創建一個 Redis 連接,執行幾個命令,然后再斷開連接,在請求量很大時,這個方式產生了嚴重的性能浪費,一半以上的命令是用來處理連接操作的,這都超過了業務邏輯上的處理,也使 Redis 變慢

解決方法:引入 proxy,他們選擇了 twitter 的 twemproxy,只需要在每個 webserver 上安裝代理,twemproxy負責與 Redis 實例進行持久連接,這樣就大大減少了連接方面的操作

twemproxy還有兩個方便的地方:

支持 memcached

可以阻止非常耗時或者危險的命令,例如 keys、flushall

效果自然很完美,再也不用擔心之前的連接錯誤

第9次

通過數據分片來繼續優化:

對不同上下文的數據拆分隔離

對相同上下文的數據進行一致性哈希分片

效果:

減少了每臺機器上的請求、負載

提升了緩存的可靠性,不擔心節點故障

小結

原文作者寫的非常好,詳細的描述了他們在 Redis 應用上的成長歷程,是很值得參考的實踐經驗

原文地址

http://tech.trivago.com/2017/01/25/learn-redis-the-hard-way-in-production

點擊 “閱讀原文” 查看 文章列表


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 土默特左旗| 鸡东县| 集贤县| 吕梁市| 贵德县| 新沂市| 嘉善县| 余姚市| 长汀县| 白山市| 海原县| 大埔区| 垣曲县| 朔州市| 桐柏县| 蒲江县| 原平市| 巴彦淖尔市| 鹤岗市| 宁德市| 濮阳市| 上思县| 和顺县| 临沂市| 澄城县| 石城县| 浏阳市| 咸阳市| 香格里拉县| 凭祥市| 文昌市| 周口市| 韶山市| 饶平县| 全椒县| 凤庆县| 岢岚县| 育儿| 新竹市| 观塘区| 平果县|