精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

從單機(jī)到2000萬(wàn)QPS:如何搭建高可用Redis平臺(tái)?

開發(fā) 架構(gòu) Redis
知乎作為知名中文知識(shí)內(nèi)容平臺(tái),每日處理的訪問(wèn)量巨大,如何更好的承載這樣巨大的訪問(wèn)量,同時(shí)提供穩(wěn)定低時(shí)延的服務(wù)保證,是知乎技術(shù)平臺(tái)同學(xué)需要面對(duì)的一大挑戰(zhàn)。

 

 

[[244283]]

 

 

 

圖片來(lái)自包圖網(wǎng)

知乎存儲(chǔ)平臺(tái)團(tuán)隊(duì)基于開源 Redis 組件打造的 Redis 平臺(tái)管理系統(tǒng),經(jīng)過(guò)不斷的研發(fā)迭代,目前已經(jīng)形成了一整套完整自動(dòng)化運(yùn)維服務(wù)體系,提供一鍵部署集群,一鍵自動(dòng)擴(kuò)縮容,Redis 超細(xì)粒度監(jiān)控,旁路流量分析等輔助功能。

目前,Redis 在知乎的規(guī)模如下:

  • 機(jī)器內(nèi)存總量約 70TB,實(shí)際使用內(nèi)存約 40TB。
  • 平均每秒處理約 1500 萬(wàn)次請(qǐng)求,峰值每秒約 2000 萬(wàn)次請(qǐng)求。
  • 每天處理約 1 萬(wàn)億余次請(qǐng)求。
  • 單集群每秒處理最高每秒約 400 萬(wàn)次請(qǐng)求。
  • 集群實(shí)例與單機(jī)實(shí)例總共約 800 個(gè)。
  • 實(shí)際運(yùn)行約 16000 個(gè) Redis 實(shí)例。
  • Redis 使用官方 3.0.7 版本,少部分實(shí)例采用 4.0.11 版本。

知乎 Redis 平臺(tái)演進(jìn)歷程

根據(jù)業(yè)務(wù)的需求,我們將實(shí)例區(qū)分為如下兩種類型:

  • 單機(jī)(Standalone),單機(jī)實(shí)例通常用于容量與性能要求不高的小型存儲(chǔ)。
  • 集群(Cluster),集群則用來(lái)應(yīng)對(duì)對(duì)性能和容量要求較高的場(chǎng)景。

單機(jī)(Standalone)

對(duì)于單機(jī)實(shí)例,我們采用原生主從(Master-Slave)模式實(shí)現(xiàn)高可用,常規(guī)模式下對(duì)外僅暴露 Master 節(jié)點(diǎn)。由于使用原生 Redis,所以單機(jī)實(shí)例支持所有 Redis 指令。

對(duì)于單機(jī)實(shí)例,我們使用 Redis 自帶的哨兵(Sentinel)集群對(duì)實(shí)例進(jìn)行狀態(tài)監(jiān)控與 Failover。

Sentinel 是 Redis 自帶的高可用組件,將 Redis 注冊(cè)到由多個(gè) Sentinel 組成的 Sentinel 集群后,Sentinel 會(huì)對(duì) Redis 實(shí)例進(jìn)行健康檢查。

當(dāng) Redis 發(fā)生故障后,Sentinel 會(huì)通過(guò) Gossip 協(xié)議進(jìn)行故障檢測(cè),確認(rèn)宕機(jī)后會(huì)通過(guò)一個(gè)簡(jiǎn)化的 Raft 協(xié)議來(lái)提升 Slave 成為新的 Master。

通常情況我們僅使用 1 個(gè) Slave 節(jié)點(diǎn)進(jìn)行冷備,如果有讀寫分離請(qǐng)求,可以建立多個(gè) Read only slave 來(lái)進(jìn)行讀寫分離。

 

如上圖所示,通過(guò)向 Sentinel 集群注冊(cè) Master 節(jié)點(diǎn)實(shí)現(xiàn)實(shí)例的高可用,當(dāng)提交 Master 實(shí)例的連接信息后,Sentinel 會(huì)主動(dòng)探測(cè)所有的 Slave 實(shí)例并建立連接,定期檢查健康狀態(tài)。

客戶端通過(guò)多種資源發(fā)現(xiàn)策略如簡(jiǎn)單的 DNS 發(fā)現(xiàn) Master 節(jié)點(diǎn),將來(lái)有計(jì)劃遷移到如 Consul 或 etcd 等資源發(fā)現(xiàn)組件 。

當(dāng) Master 節(jié)點(diǎn)發(fā)生宕機(jī)時(shí),Sentinel 集群會(huì)提升 Slave 節(jié)點(diǎn)為新的 Master,同時(shí)在自身的 pubsub channel +switch-master 廣播切換的消息,具體消息格式為:

  1. switch-master <master name> <oldip> <oldport> <newip> <newport> 

Watcher 監(jiān)聽到消息后,會(huì)去主動(dòng)更新資源發(fā)現(xiàn)策略,將客戶端連接指向新的 Master 節(jié)點(diǎn),完成 Failover。

實(shí)際使用中需要注意以下幾點(diǎn):

  • 只讀 Slave 節(jié)點(diǎn)可以按照需求設(shè)置 slave-priority 參數(shù)為 0,防止故障切換時(shí)選擇了只讀節(jié)點(diǎn)而不是熱備 Slave 節(jié)點(diǎn)。
  • Sentinel 進(jìn)行故障切換后會(huì)執(zhí)行 CONFIG REWRITE 命令將 SLAVEOF 配置落地,如果 Redis 配置中禁用了 CONFIG 命令,切換時(shí)會(huì)發(fā)生錯(cuò)誤,可以通過(guò)修改 Sentinel 代碼來(lái)替換 CONFIG 命令。
  • Sentinel Group 監(jiān)控的節(jié)點(diǎn)不宜過(guò)多,實(shí)測(cè)超過(guò) 500 個(gè)切換過(guò)程偶爾會(huì)進(jìn)入 TILT 模式,導(dǎo)致 Sentinel 工作不正常,推薦部署多個(gè) Sentinel 集群并保證每個(gè)集群監(jiān)控的實(shí)例數(shù)量小于 300 個(gè)。
  • Master 節(jié)點(diǎn)應(yīng)與 Slave 節(jié)點(diǎn)跨機(jī)器部署,有能力的使用方可以跨機(jī)架部署,不推薦跨機(jī)房部署 Redis 主從實(shí)例。
  • Sentinel 切換功能主要依賴 down-after-milliseconds 和failover-timeout 兩個(gè)參數(shù),down-after-milliseconds 決定了Sentinel 判斷 Redis 節(jié)點(diǎn)宕機(jī)的超時(shí),知乎使用 30000 作為閾值。

而 failover-timeout 則決定了兩次切換之間的最短等待時(shí)間,如果對(duì)于切換成功率要求較高,可以適當(dāng)縮短 failover-timeout 到秒級(jí)保證切換成功。

  • 單機(jī)網(wǎng)絡(luò)故障等同于機(jī)器宕機(jī),但如果機(jī)房全網(wǎng)發(fā)生大規(guī)模故障會(huì)造成主從多次切換,此時(shí)資源發(fā)現(xiàn)服務(wù)可能更新不夠及時(shí),需要人工介入。

集群(Cluster)

當(dāng)實(shí)例需要的容量超過(guò) 20G 或要求的吞吐量超過(guò) 20 萬(wàn)請(qǐng)求每秒時(shí),我們會(huì)使用集群(Cluster)實(shí)例來(lái)承擔(dān)流量。

集群是通過(guò)中間件(客戶端或中間代理等)將流量分散到多個(gè) Redis 實(shí)例上的解決方案。

知乎的 Redis 集群方案經(jīng)歷了兩個(gè)階段:

  • 客戶端分片
  • Twemproxy 代理

客戶端分片(before 2015)

早期知乎使用 redis-shard 進(jìn)行客戶端分片,redis-shard 庫(kù)內(nèi)部實(shí)現(xiàn)了 CRC32、MD5、SHA1 三種哈希算法,支持絕大部分Redis 命令。使用者只需把 redis-shard 當(dāng)成原生客戶端使用即可,無(wú)需關(guān)注底層分片。


 

 

基于客戶端的分片模式具有如下優(yōu)點(diǎn):

  • 基于客戶端分片的方案是集群方案中最快的,沒有中間件,僅需要客戶端進(jìn)行一次哈希計(jì)算,不需要經(jīng)過(guò)代理,沒有官方集群方案的 MOVED/ASK 轉(zhuǎn)向。
  • 不需要多余的 Proxy 機(jī)器,不用考慮 Proxy 部署與維護(hù)。
  • 可以自定義更適合生產(chǎn)環(huán)境的哈希算法。

但是也存在如下問(wèn)題:

  • 需要每種語(yǔ)言都實(shí)現(xiàn)一遍客戶端邏輯,早期知乎全站使用 Python 進(jìn)行開發(fā),但是后來(lái)業(yè)務(wù)線增多,使用的語(yǔ)言增加至 Python,Golang,Lua,C/C++,JVM 系(Java,Scala,Kotlin)等,維護(hù)成本過(guò)高。
  • 無(wú)法正常使用 MSET、MGET 等多種同時(shí)操作多個(gè) Key 的命令,需要使用 Hash tag 來(lái)保證多個(gè) Key 在同一個(gè)分片上。
  • 升級(jí)麻煩,升級(jí)客戶端需要所有業(yè)務(wù)升級(jí)更新重啟,業(yè)務(wù)規(guī)模變大后無(wú)法推動(dòng)。
  • 擴(kuò)容困難,存儲(chǔ)需要停機(jī)使用腳本 Scan 所有的 Key 進(jìn)行遷移,緩存只能通過(guò)傳統(tǒng)的翻倍取模方式進(jìn)行擴(kuò)容。
  • 由于每個(gè)客戶端都要與所有的分片建立池化連接,客戶端基數(shù)過(guò)大時(shí)會(huì)造成 Redis 端連接數(shù)過(guò)多,Redis 分片過(guò)多時(shí)會(huì)造成 Python 客戶端負(fù)載升高。
  • 早期知乎大部分業(yè)務(wù)由 Python 構(gòu)建,Redis 使用的容量波動(dòng)較小,redis-shard 很好地應(yīng)對(duì)了這個(gè)時(shí)期的業(yè)務(wù)需求,在當(dāng)時(shí)是一個(gè)較為不錯(cuò)的解決方案。

Twemproxy 集群 (2015 - Now)

2015 年開始,業(yè)務(wù)上漲迅猛,Redis 需求暴增,原有的 redis-shard 模式已經(jīng)無(wú)法滿足日益增長(zhǎng)的擴(kuò)容需求,我們開始調(diào)研多種集群方案,最終選擇了簡(jiǎn)單高效的 Twemproxy 作為我們的集群方案。

由 Twitter 開源的 Twemproxy 具有如下優(yōu)點(diǎn):

  • 性能很好且足夠穩(wěn)定,自建內(nèi)存池實(shí)現(xiàn) Buffer 復(fù)用,代碼質(zhì)量很高。
  • 支持 fnv1a_64、murmur、md5 等多種哈希算法。
  • 支持一致性哈希(ketama),取模哈希(modula)和隨機(jī)(random)三種分布式算法。

但是缺點(diǎn)也很明顯:

  • 單核模型造成性能瓶頸。
  • 傳統(tǒng)擴(kuò)容模式僅支持停機(jī)擴(kuò)容。

對(duì)此,我們將集群實(shí)例分成兩種模式:

  • 緩存(Cache)
  • 存儲(chǔ)(Storage)

如果使用方可以接受通過(guò)損失一部分少量數(shù)據(jù)來(lái)保證可用性,或使用方可以從其余存儲(chǔ)恢復(fù)實(shí)例中的數(shù)據(jù),這種實(shí)例即為緩存,其余情況均為存儲(chǔ)。我們對(duì)緩存和存儲(chǔ)采用了不同的策略。

存儲(chǔ)

 

對(duì)于存儲(chǔ)我們使用 fnv1a_64 算法結(jié)合 modula 模式即取模哈希對(duì) Key 進(jìn)行分片。

底層 Redis 使用單機(jī)模式結(jié)合 Sentinel 集群實(shí)現(xiàn)高可用,默認(rèn)使用 1 個(gè) Master 節(jié)點(diǎn)和 1 個(gè) Slave 節(jié)點(diǎn)提供服務(wù),如果業(yè)務(wù)有更高的可用性要求,可以拓展 Slave 節(jié)點(diǎn)。

當(dāng)集群中 Master 節(jié)點(diǎn)宕機(jī),按照單機(jī)模式下的高可用流程進(jìn)行切換,Twemproxy 在連接斷開后會(huì)進(jìn)行重連。

對(duì)于存儲(chǔ)模式下的集群,我們不會(huì)設(shè)置 auto_eject_hosts,不會(huì)剔除節(jié)點(diǎn)。

同時(shí),對(duì)于存儲(chǔ)實(shí)例,我們默認(rèn)使用 noeviction 策略,在內(nèi)存使用超過(guò)規(guī)定的額度時(shí)直接返回 OOM 錯(cuò)誤,不會(huì)主動(dòng)進(jìn)行 Key 的刪除,保證數(shù)據(jù)的完整性。

由于 Twemproxy 僅進(jìn)行高性能的命令轉(zhuǎn)發(fā),不進(jìn)行讀寫分離,所以默認(rèn)沒有讀寫分離功能。

而在實(shí)際使用過(guò)程中,我們也沒有遇到集群讀寫分離的需求,如果要進(jìn)行讀寫分離,可以使用資源發(fā)現(xiàn)策略在 Slave 節(jié)點(diǎn)上架設(shè) Twemproxy 集群,由客戶端進(jìn)行讀寫分離的路由。

緩存

考慮到對(duì)于后端(MySQL/HBase/RPC 等)的壓力,知乎絕大部分業(yè)務(wù)都沒有針對(duì)緩存進(jìn)行降級(jí),這種情況下對(duì)緩存的可用性要求較數(shù)據(jù)的一致性要求更高。

但是如果按照存儲(chǔ)的主從模式實(shí)現(xiàn)高可用,1 個(gè) Slave 節(jié)點(diǎn)的部署策略在線上環(huán)境只能容忍 1 臺(tái)物理節(jié)點(diǎn)宕機(jī),N 臺(tái)物理節(jié)點(diǎn)宕機(jī)高可用就需要至少 N 個(gè) Slave 節(jié)點(diǎn),這無(wú)疑是種資源的浪費(fèi)。

 

所以我們采用了 Twemproxy 一致性哈希(Consistent Hashing)策略來(lái)配合 auto_eject_hosts 自動(dòng)彈出策略組建 Redis 緩存集群。

對(duì)于緩存我們?nèi)匀皇褂?fnv1a_64 算法進(jìn)行哈希計(jì)算,但是分布算法我們使用了 ketama 即一致性哈希進(jìn)行 Key 分布。緩存節(jié)點(diǎn)沒有主從,每個(gè)分片僅有 1 個(gè) Master 節(jié)點(diǎn)承載流量。

Twemproxy 配置 auto_eject_hosts 會(huì)在實(shí)例連接失敗超過(guò)server_failure_limit 次的情況下剔除節(jié)點(diǎn)。

并在 server_retry_timeout 超時(shí)之后進(jìn)行重試,剔除后配合 ketama 一致性哈希算法重新計(jì)算哈希環(huán),恢復(fù)正常使用,這樣即使一次宕機(jī)多個(gè)物理節(jié)點(diǎn)仍然能保持服務(wù)。


 

在實(shí)際的生產(chǎn)環(huán)境中需要注意以下幾點(diǎn):

  • 剔除節(jié)點(diǎn)后,會(huì)造成短時(shí)間的命中率下降,后端存儲(chǔ)如 MySQL、HBase 等需要做好流量監(jiān)測(cè)。
  • 線上環(huán)境緩存后端分片不宜過(guò)大,建議維持在 20G 以內(nèi),同時(shí)分片調(diào)度應(yīng)盡可能分散,這樣即使宕機(jī)一部分節(jié)點(diǎn),對(duì)后端造成的額外的壓力也不會(huì)太多。
  • 機(jī)器宕機(jī)重啟后,緩存實(shí)例需要清空數(shù)據(jù)之后啟動(dòng),否則原有的緩存數(shù)據(jù)和新建立的緩存數(shù)據(jù)會(huì)沖突導(dǎo)致臟緩存。

直接不啟動(dòng)緩存也是一種方法,但是在分片宕機(jī)期間會(huì)導(dǎo)致周期性 server_failure_limit 次數(shù)的連接失敗。

  • server_retry_timeout 和 server_failure_limit 需要仔細(xì)敲定確認(rèn),知乎使用 10min 和 3 次作為配置,即連接失敗 3 次后剔除節(jié)點(diǎn),10 分鐘后重新進(jìn)行連接。

Twemproxy 部署

在方案早期我們使用數(shù)量固定的物理機(jī)部署 Twemproxy,通過(guò)物理機(jī)上的 Agent 啟動(dòng)實(shí)例,Agent 在運(yùn)行期間會(huì)對(duì) Twemproxy 進(jìn)行健康檢查與故障恢復(fù)。

由于 Twemproxy 僅提供全量的使用計(jì)數(shù),所以 Agent 運(yùn)行時(shí)還會(huì)進(jìn)行定時(shí)的差值計(jì)算來(lái)計(jì)算 Twemproxy 的 requests_per_second 等指標(biāo)。

后來(lái)為了更好地故障檢測(cè)和資源調(diào)度,我們引入了 Kubernetes,將 Twemproxy 和 Agent 放入同一個(gè) Pod 的兩個(gè)容器內(nèi),底層 Docker 網(wǎng)段的配置使每個(gè) Pod 都能獲得獨(dú)立的 IP,方便管理。

最開始,本著簡(jiǎn)單易用的原則,我們使用 DNS A Record 來(lái)進(jìn)行客戶端的資源發(fā)現(xiàn),每個(gè) Twemproxy 采用相同的端口號(hào),一個(gè) DNS A Record 后面掛接多個(gè) IP 地址對(duì)應(yīng)多個(gè) Twemproxy 實(shí)例。

初期,這種方案簡(jiǎn)單易用,但是到了后期流量日益上漲,單集群 Twemproxy 實(shí)例個(gè)數(shù)很快就超過(guò)了 20 個(gè)。

由于 DNS 采用的 UDP 協(xié)議有 512 字節(jié)的包大小限制,單個(gè) A Record 只能掛接 20 個(gè)左右的 IP 地址,超過(guò)這個(gè)數(shù)字就會(huì)轉(zhuǎn)換為 TCP 協(xié)議,客戶端不做處理就會(huì)報(bào)錯(cuò),導(dǎo)致客戶端啟動(dòng)失敗。

當(dāng)時(shí)由于情況緊急,只能建立多個(gè) Twemproxy Group,提供多個(gè) DNS A Record 給客戶端,客戶端進(jìn)行輪詢或者隨機(jī)選擇,該方案可用,但是不夠優(yōu)雅。

如何解決 Twemproxy 單 CPU 計(jì)算能力的限制?

之后我們修改了 Twemproxy 源碼, 加入 SO_REUSEPORT 支持。

 

Twemproxy with SO_REUSEPORT on Kubernetes

同一個(gè)容器內(nèi)由 Starter 啟動(dòng)多個(gè) Twemproxy 實(shí)例并綁定到同一個(gè)端口,由操作系統(tǒng)進(jìn)行負(fù)載均衡,對(duì)外仍然暴露一個(gè)端口,但是內(nèi)部已經(jīng)由系統(tǒng)均攤到了多個(gè) Twemproxy 上。

同時(shí) Starter 會(huì)定時(shí)去每個(gè) Twemproxy 的 stats 端口獲取 Twemproxy 運(yùn)行狀態(tài)進(jìn)行聚合,此外 Starter 還承載了信號(hào)轉(zhuǎn)發(fā)的職責(zé)。

原有的Agent 不需要用來(lái)啟動(dòng) Twemproxy 實(shí)例,所以 Monitor 調(diào)用 Starter 獲取聚合后的 stats 信息進(jìn)行差值計(jì)算,最終對(duì)外界暴露出實(shí)時(shí)的運(yùn)行狀態(tài)信息。

為什么沒有使用官方 Redis 集群方案?

我們?cè)?2015 年調(diào)研過(guò)多種集群方案,綜合評(píng)估多種方案后,最終選擇了看起來(lái)較為陳舊的 Twemproxy 而不是官方 Redis 集群方案與 Codis,具體原因如下:

MIGRATE 造成的阻塞問(wèn)題:Redis 官方集群方案使用 CRC16 算法計(jì)算哈希值并將 Key 分散到 16384 個(gè) Slot 中,由使用方自行分配 Slot 對(duì)應(yīng)到每個(gè)分片中。

擴(kuò)容時(shí)由使用方自行選擇 Slot 并對(duì)其進(jìn)行遍歷,對(duì) Slot 中每一個(gè) Key 執(zhí)行 MIGRATE 命令進(jìn)行遷移。

調(diào)研后發(fā)現(xiàn),MIGRATE 命令實(shí)現(xiàn)分為三個(gè)階段:

  • DUMP 階段:由源實(shí)例遍歷對(duì)應(yīng) Key 的內(nèi)存空間,將 Key 對(duì)應(yīng)的 Redis Object 序列化,序列化協(xié)議跟 Redis RDB 過(guò)程一致。
  • RESTORE 階段:由源實(shí)例建立 TCP 連接到對(duì)端實(shí)例,并將 DUMP 出來(lái)的內(nèi)容使用 RESTORE 命令到對(duì)端進(jìn)行重建,新版本的 Redis 會(huì)緩存對(duì)端實(shí)例的連接。
  • DEL 階段(可選):如果發(fā)生遷移失敗,可能會(huì)造成同名的 Key 同時(shí)存在于兩個(gè)節(jié)點(diǎn)。

此時(shí) MIGRATE 的 REPLACE 參數(shù)決定是否覆蓋對(duì)端的同名 Key,如果覆蓋,對(duì)端的 Key 會(huì)進(jìn)行一次刪除操作,4.0 版本之后刪除可以異步進(jìn)行,不會(huì)阻塞主進(jìn)程。

經(jīng)過(guò)調(diào)研,我們認(rèn)為這種模式并不適合知乎的生產(chǎn)環(huán)境。Redis 為了保證遷移的一致性, MIGRATE 所有操作都是同步操作,執(zhí)行 MIGRATE 時(shí),兩端的 Redis 均會(huì)進(jìn)入時(shí)長(zhǎng)不等的 BLOCK 狀態(tài)。

對(duì)于小 Key,該時(shí)間可以忽略不計(jì),但如果一旦 Key 的內(nèi)存使用過(guò)大,一個(gè) MIGRATE 命令輕則導(dǎo)致 P95 尖刺,重則直接觸發(fā)集群內(nèi)的 Failover,造成不必要的切換。

同時(shí),遷移過(guò)程中訪問(wèn)到處于遷移中間狀態(tài)的Slot 的 Key 時(shí),根據(jù)進(jìn)度可能會(huì)產(chǎn)生 ASK 轉(zhuǎn)向,此時(shí)需要客戶端發(fā)送 ASKING 命令到 Slot 所在的另一個(gè)分片重新請(qǐng)求,請(qǐng)求時(shí)延則會(huì)變?yōu)樵瓉?lái)的兩倍。

同樣,方案初期時(shí)的 Codis 采用的是相同的 MIGRATE 方案,但是使用 Proxy 控制 Redis 進(jìn)行遷移操作而非第三方腳本(如 redis-trib.rb),基于同步的類似 MIGRATE 的命令,實(shí)際跟 Redis 官方集群方案存在同樣的問(wèn)題。

對(duì)于這種 Huge Key 問(wèn)題決定權(quán)完全在于業(yè)務(wù)方,有時(shí)業(yè)務(wù)需要不得不產(chǎn)生 Huge Key 時(shí)會(huì)十分尷尬,如關(guān)注列表。

一旦業(yè)務(wù)使用不當(dāng)出現(xiàn)超過(guò) 1MB 以上的大 Key 便會(huì)導(dǎo)致數(shù)十毫秒的延遲,遠(yuǎn)高于平時(shí) Redis 亞毫秒級(jí)的延遲。

有時(shí),在 Slot 遷移過(guò)程中業(yè)務(wù)不慎同時(shí)寫入了多個(gè)巨大的 Key 到 Slot 遷移的源節(jié)點(diǎn)和目標(biāo)節(jié)點(diǎn),除非寫腳本刪除這些 Key ,否則遷移會(huì)進(jìn)入進(jìn)退兩難的地步。

對(duì)此,Redis 作者在 Redis 4.2 的 roadmap[5] 中提到了 Non blocking MIGRATE。

但是截至目前,Redis 5.0 即將正式發(fā)布,仍未看到有關(guān)改動(dòng),社區(qū)中已經(jīng)有相關(guān)的 Pull Request [6],該功能可能會(huì)在 5.2 或者 6.0 之后并入 Master 分支,對(duì)此我們將持續(xù)觀望。

緩存模式下高可用方案不夠靈活:還有,官方集群方案的高可用策略僅有主從一種,高可用級(jí)別跟 Slave 的數(shù)量成正相關(guān)。

如果只有一個(gè) Slave,則只能允許一臺(tái)物理機(jī)器宕機(jī),Redis 4.2 roadmap 提到了 cache-only mode,提供類似于 Twemproxy 的自動(dòng)剔除后重分片策略,但是截至目前仍未實(shí)現(xiàn)。

內(nèi)置 Sentinel 造成額外流量負(fù)載:另外,官方 Redis 集群方案將 Sentinel 功能內(nèi)置到 Redis 內(nèi),這導(dǎo)致在節(jié)點(diǎn)數(shù)較多(大于 100)時(shí)在 Gossip 階段會(huì)產(chǎn)生大量的 PING/INFO/CLUSTER INFO 流量。

根據(jù) issue 中提到的情況,200 個(gè)使用 3.2.8 版本節(jié)點(diǎn)搭建的 Redis 集群,在沒有任何客戶端請(qǐng)求的情況下,每個(gè)節(jié)點(diǎn)仍然會(huì)產(chǎn)生 40Mb/s 的流量。

雖然到后期 Redis 官方嘗試對(duì)其進(jìn)行壓縮修復(fù),但按照 Redis 集群機(jī)制,節(jié)點(diǎn)較多的情況下無(wú)論如何都會(huì)產(chǎn)生這部分流量,對(duì)于使用大內(nèi)存機(jī)器但是使用千兆網(wǎng)卡的用戶這是一個(gè)值得注意的地方。

Slot 存儲(chǔ)開銷:最后,每個(gè)Key 對(duì)應(yīng)的 Slot 的存儲(chǔ)開銷,在規(guī)模較大的時(shí)候會(huì)占用較多內(nèi)存,4.x 版本以前甚至?xí)_(dá)到實(shí)際使用內(nèi)存的數(shù)倍。

雖然 4.x 版本使用 rax 結(jié)構(gòu)進(jìn)行存儲(chǔ),但是仍然占據(jù)了大量?jī)?nèi)存,從非官方集群方案遷移到官方集群方案時(shí),需要注意這部分多出來(lái)的內(nèi)存。

總之,官方 Redis 集群方案與 Codis 方案對(duì)于絕大多數(shù)場(chǎng)景來(lái)說(shuō)都是非常優(yōu)秀的解決方案。

但是我們仔細(xì)調(diào)研發(fā)現(xiàn)并不是很適合集群數(shù)量較多且使用方式多樣化的我們,場(chǎng)景不同側(cè)重點(diǎn)也會(huì)不一樣,但在此仍然要感謝開發(fā)這些組件的開發(fā)者們,感謝你們對(duì) Redis 社區(qū)的貢獻(xiàn)。

擴(kuò)容

靜態(tài)擴(kuò)容

對(duì)于單機(jī)實(shí)例,如果通過(guò)調(diào)度器觀察到對(duì)應(yīng)的機(jī)器仍然有空閑的內(nèi)存,我們僅需直接調(diào)整實(shí)例的 maxmemory 配置與報(bào)警即可。

同樣,對(duì)于集群實(shí)例,我們通過(guò)調(diào)度器觀察每個(gè)節(jié)點(diǎn)所在的機(jī)器,如果所有節(jié)點(diǎn)所在機(jī)器均有空閑內(nèi)存,我們會(huì)像擴(kuò)容單機(jī)實(shí)例一樣直接更新 maxmemory 與報(bào)警。

動(dòng)態(tài)擴(kuò)容

但是當(dāng)機(jī)器空閑內(nèi)存不夠,或單機(jī)實(shí)例與集群的后端實(shí)例過(guò)大時(shí),無(wú)法直接擴(kuò)容,需要進(jìn)行動(dòng)態(tài)擴(kuò)容:

  • 對(duì)于單機(jī)實(shí)例,如果單實(shí)例超過(guò) 30GB 且沒有如 sinterstore 之類的多 Key 操作,我們會(huì)將其擴(kuò)容為集群實(shí)例。
  • 對(duì)于集群實(shí)例,我們會(huì)進(jìn)行橫向的重分片,我們稱之為 Resharding 過(guò)程。

 

Resharding 過(guò)程

原生 Twemproxy 集群方案并不支持?jǐn)U容,我們開發(fā)了數(shù)據(jù)遷移工具來(lái)進(jìn)行 Twemproxy 的擴(kuò)容,遷移工具本質(zhì)上是一個(gè)上下游之間的代理,將數(shù)據(jù)從上游按照新的分片方式搬運(yùn)到下游。

原生 Redis 主從同步使用 SYNC/PSYNC 命令建立主從連接,收到 SYNC 命令的 Master 會(huì) fork 出一個(gè)進(jìn)程遍歷內(nèi)存空間生成 RDB 文件并發(fā)送給 Slave。

期間所有發(fā)送至 Master 的寫命令在執(zhí)行的同時(shí)都會(huì)被緩存到內(nèi)存的緩沖區(qū)內(nèi),當(dāng) RDB 發(fā)送完成后,Master 會(huì)將緩沖區(qū)內(nèi)的命令及之后的寫命令轉(zhuǎn)發(fā)給 Slave 節(jié)點(diǎn)。

我們開發(fā)的遷移代理會(huì)向上游發(fā)送 SYNC 命令模擬上游實(shí)例的 Slave,代理收到 RDB 后進(jìn)行解析。

由于 RDB 中每個(gè) Key 的格式與 RESTORE 命令的格式相同,所以我們使用生成 RESTORE 命令按照下游的 Key 重新計(jì)算哈希并使用 Pipeline 批量發(fā)送給下游。

等待 RDB 轉(zhuǎn)發(fā)完成后,我們按照新的后端生成新的 Twemproxy 配置,并按照新的 Twemproxy 配置建立 Canary 實(shí)例。

從上游的 Redis 后端中取 Key 進(jìn)行測(cè)試,測(cè)試 Resharding 過(guò)程是否正確,測(cè)試過(guò)程中的 Key 按照大小,類型,TTL 進(jìn)行比較。

測(cè)試通過(guò)后,對(duì)于集群實(shí)例,我們使用生成好的配置替代原有 Twemproxy 配置并 restart/reload Twemproxy 代理。

我們修改了 Twemproxy 代碼,加入了 config reload 功能,但是實(shí)際使用中發(fā)現(xiàn)直接重啟實(shí)例更加可控。

而對(duì)于單機(jī)實(shí)例,由于單機(jī)實(shí)例和集群實(shí)例對(duì)于命令的支持不同,通常需要和業(yè)務(wù)方確定后手動(dòng)重啟切換。

由于 Twemproxy 部署于 Kubernetes ,我們可以實(shí)現(xiàn)細(xì)粒度的灰度,如果客戶端接入了讀寫分離,我們可以先將讀流量接入新集群,最終接入全部流量。

這樣相對(duì)于 Redis 官方集群方案,除在上游進(jìn)行 BGSAVE 時(shí)的 fork 復(fù)制頁(yè)表時(shí)造成的尖刺以及重啟時(shí)造成的連接閃斷,其余對(duì)于 Redis 上游造成的影響微乎其微。

這樣擴(kuò)容存在的問(wèn)題:

對(duì)上游發(fā)送 SYNC 后,上游fork 時(shí)會(huì)造成尖刺:對(duì)于存儲(chǔ)實(shí)例,我們使用Slave 進(jìn)行數(shù)據(jù)同步,不會(huì)影響到接收請(qǐng)求的 Master 節(jié)點(diǎn)。

對(duì)于緩存實(shí)例,由于沒有 Slave 實(shí)例,該尖刺無(wú)法避免,如果對(duì)于尖刺過(guò)于敏感,我們可以跳過(guò) RDB 階段,直接通過(guò) PSYNC 使用最新的 SET 消息建立下游的緩存。

切換過(guò)程中有可能寫到下游,而讀在上游:對(duì)于接入了讀寫分離的客戶端,我們會(huì)先切換讀流量到下游實(shí)例,再切換寫流量。

一致性問(wèn)題:兩條具有先后順序的寫同一個(gè) Key 命令在切換代理后端時(shí)會(huì)通過(guò) 1)寫上游同步到下游 2)直接寫到下游兩種方式寫到下游。

此時(shí),可能存在應(yīng)先執(zhí)行的命令卻通過(guò) 1)執(zhí)行落后于通過(guò) 2)執(zhí)行,導(dǎo)致命令先后順序倒置。

這個(gè)問(wèn)題在切換過(guò)程中無(wú)法避免,好在絕大部分應(yīng)用沒有這種問(wèn)題,如果無(wú)法接受,只能通過(guò)上游停寫排空 Resharding 代理保證先后順序。

官方 Redis 集群方案和 Codis 會(huì)通過(guò) blocking 的 MIGRATE 命令來(lái)保證一致性,不存在這種問(wèn)題。

實(shí)際使用過(guò)程中,如果上游分片安排合理,可實(shí)現(xiàn)數(shù)千萬(wàn)次每秒的遷移速度,1TB 的實(shí)例 Resharding 只需要半小時(shí)左右。

另外,對(duì)于實(shí)際生產(chǎn)環(huán)境來(lái)說(shuō),提前做好預(yù)期規(guī)劃比遇到問(wèn)題緊急擴(kuò)容要快且安全得多。

旁路分析

由于生產(chǎn)環(huán)境調(diào)試需要,有時(shí)會(huì)需要監(jiān)控線上 Redis 實(shí)例的訪問(wèn)情況,Redis 提供了多種監(jiān)控手段,如 MONITOR 命令。

但由于 Redis 單線程的限制,導(dǎo)致自帶的 MONITOR 命令在負(fù)載過(guò)高的情況下會(huì)再次跑高 CPU,對(duì)于生產(chǎn)環(huán)境來(lái)說(shuō)過(guò)于危險(xiǎn)。

而其余方式如 Keyspace Notify 只有寫事件,沒有讀事件,無(wú)法做到細(xì)致的觀察。

對(duì)此我們開發(fā)了基于 libpcap 的旁路分析工具,系統(tǒng)層面復(fù)制流量,對(duì)應(yīng)用層流量進(jìn)行協(xié)議分析,實(shí)現(xiàn)旁路 MONITOR,實(shí)測(cè)對(duì)于運(yùn)行中的實(shí)例影響微乎其微。

同時(shí)對(duì)于沒有 MONITOR 命令的 Twemproxy,旁路分析工具仍能進(jìn)行分析。

由于生產(chǎn)環(huán)境中絕大部分業(yè)務(wù)都使用 Kubernetes 部署于 Docker 內(nèi) ,每個(gè)容器都有對(duì)應(yīng)的獨(dú)立 IP。

所以可以使用旁路分析工具反向解析找出客戶端所在的應(yīng)用,分析業(yè)務(wù)方的使用模式,防止不正常的使用。

將來(lái)的工作

由于 Redis 5.0 發(fā)布在即,4.0 版本趨于穩(wěn)定,我們將逐步升級(jí)實(shí)例到 4.0 版本,由此帶來(lái)的如 MEMORY 命令、Redis Module 、新的 LFU 算法等特性無(wú)論對(duì)運(yùn)維方還是業(yè)務(wù)方都有極大的幫助。

最后

知乎架構(gòu)平臺(tái)團(tuán)隊(duì)是支撐整個(gè)知乎業(yè)務(wù)的基礎(chǔ)技術(shù)團(tuán)隊(duì),開發(fā)和維護(hù)著知乎幾乎全量的核心基礎(chǔ)組件。

包括容器、Redis、MySQL、Kafka、LB、HBase 等核心基礎(chǔ)設(shè)施,團(tuán)隊(duì)小而精,每個(gè)同學(xué)都獨(dú)當(dāng)一面負(fù)責(zé)上面提到的某個(gè)核心系統(tǒng)。

隨著知乎業(yè)務(wù)規(guī)模的快速增長(zhǎng),以及業(yè)務(wù)復(fù)雜度的持續(xù)增加,團(tuán)隊(duì)面臨的技術(shù)挑戰(zhàn)也越來(lái)越大。

參考資料:

  • Redis Official site

https://redis.io/

  • Twemproxy Github Page

https://github.com/twitter/twemproxy

  • Codis Github Page

https://github.com/CodisLabs/codis

  • SO_REUSEPORT Man Page

http://man7.org/linux/man-pages/man7/socket.7.html

  • Kubernetes

https://kubernetes.io/

作者:陳鵬

簡(jiǎn)介:現(xiàn)知乎存儲(chǔ)平臺(tái)組 Redis 平臺(tái)技術(shù)負(fù)責(zé)人,2014 年加入知乎技術(shù)平臺(tái)組從事基礎(chǔ)架構(gòu)相關(guān)系統(tǒng)的開發(fā)與運(yùn)維,從無(wú)到有建立了知乎 Redis 平臺(tái),承載了知乎高速增長(zhǎng)的業(yè)務(wù)流量。

 

責(zé)任編輯:武曉燕 來(lái)源: 高可用架構(gòu)
相關(guān)推薦

2017-05-27 09:23:10

IOS框架APP框架代碼

2018-06-06 09:48:18

保障系統(tǒng)高可用

2022-04-18 10:54:49

券系統(tǒng)緩存 RedisMySQL

2025-07-31 04:00:00

2025-04-27 01:22:00

QPS高并發(fā)MySQL

2020-07-24 08:50:17

Redis數(shù)據(jù)庫(kù)

2023-11-13 09:03:10

2018-12-19 09:00:07

Redis主從架構(gòu)數(shù)據(jù)庫(kù)

2012-05-03 13:20:18

萬(wàn)網(wǎng)

2024-02-28 10:14:47

Redis數(shù)據(jù)硬盤

2021-04-26 09:40:46

QPS數(shù)據(jù)庫(kù)Redis

2024-07-25 08:39:48

2022-05-16 13:46:38

Redis高可用Sentinel

2022-06-21 07:51:06

Redis高可用哨兵進(jìn)程

2019-05-27 15:13:31

Redis服務(wù)高可用

2025-06-23 08:23:04

2022-06-13 07:02:02

Zadig平臺(tái)自動(dòng)化

2023-04-11 08:30:52

2014-10-09 10:04:23

CentOS集群

2024-12-09 00:00:09

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

国产成人综合精品在线| 亚洲国产精品字幕| 亚洲小说欧美另类激情| av官网在线观看| 中文一区在线| 中文一区二区视频| 岛国精品一区二区三区| 国产综合色区在线观看| 亚洲欧洲在线观看av| 成人午夜激情免费视频| 国产精品二区一区二区aⅴ| 亚洲精品进入| 欧美一区二区三区日韩| 国产亚洲综合视频| 麻豆传媒视频在线观看| 不卡的av电影| 成人精品视频久久久久| 国产精品免费av一区二区| 第一会所亚洲原创| 亚洲国产精久久久久久久| 超碰在线人人爱| 成人超碰在线| 亚洲视频你懂的| 欧美日韩精品久久久免费观看| 亚洲一卡二卡在线| 一区二区高清| 美女撒尿一区二区三区| 日本黄色特级片| 日韩08精品| 欧美色欧美亚洲另类二区| 久草视频这里只有精品| √天堂资源地址在线官网| 成人av免费在线| 4444kk亚洲人成电影在线| 无码久久精品国产亚洲av影片| 欧美天天视频| 不卡中文字幕av| 国产视频123区| 亚洲精华一区二区三区| 亚洲国产91精品在线观看| 乳色吐息在线观看| 免费不卡av在线| 国产精品国产高清国产| 国产精品中文字幕欧美| 国产精品丝袜久久久久久不卡| 日本高清www免费视频| 欧美成人嫩草网站| 久久久999精品| 国产精品酒店视频| 国产一区二区三区四区五区| 日韩高清不卡av| xxxxwww一片| 国产日韩欧美中文在线| 欧美色综合天天久久综合精品| 黄色免费观看视频网站| 超碰99在线| 亚洲国产成人av网| 久无码久无码av无码| 国产黄色小视频在线| 国产精品精品国产色婷婷| 日韩免费av一区二区三区| 黄色大片在线看| 国产午夜精品理论片a级大结局| 久久久久久草| 你懂的视频在线| 久久中文娱乐网| 欧美日韩国产免费一区二区三区| 欧美日韩在线中文字幕| 91日韩一区二区三区| 麻豆91蜜桃| 国内精品一区视频| 亚洲国产精品成人综合| 杨幂一区欧美专区| a免费在线观看| 亚洲综合在线第一页| 免费高清一区二区三区| 99爱在线视频| 色婷婷精品久久二区二区蜜臀av | 色婷婷av一区二区三区之e本道| 成人免费的视频| 精品一区二区久久久久久久网站| 亚洲色图 校园春色| 国产女人水真多18毛片18精品视频 | 国产青草视频在线观看| 成人福利电影| 91福利在线看| 一起草最新网址| 澳门精品久久国产| 亚洲女人初尝黑人巨大| 手机毛片在线观看| 国产真实久久| 日韩美女毛茸茸| 国产精品久久久久久免费| 国产成人在线影院 | 免费观看黄色av| 久久婷婷国产综合精品青草| 色姑娘综合网| 青青青国内视频在线观看软件| 五月天婷婷综合| 日本在线观看免费视频| 日韩三级不卡| 亚洲视频网站在线观看| 中国毛片直接看| 亚洲欧美成人综合| 成人网中文字幕| 日本一卡二卡四卡精品| 亚洲色图欧洲色图婷婷| 国产美女三级视频| 精品国模一区二区三区欧美 | 色婷婷综合久久久中文一区二区 | 2024国产精品| 成人综合在线网站| 国产日韩一区二区三区| 国产黄在线看| 亚洲午夜精品网| 久久久精品麻豆| 超碰97久久国产精品牛牛| 中文字幕日韩综合av| 黄网站免费在线| 久久黄色级2电影| 美乳视频一区二区| 伊人在我在线看导航| 在线观看成人免费视频| 亚洲美女在线播放| 一区二区在线| 国产精品免费在线免费| 色婷婷激情五月| 亚洲欧美韩国综合色| www.射射射| 日本在线视频一区二区三区| 中文字幕亚洲欧美日韩2019| 久久亚洲精品国产| 成人aa视频在线观看| 91国在线高清视频| 黄色录像a级片| 日韩影院二区| 国产成人精品亚洲精品| 深夜视频在线免费| 午夜精品福利一区二区蜜股av| 中文字幕55页| 99国产精品免费视频观看| 国产精品夫妻激情| 大胆av不用播放器在线播放| 色偷偷成人一区二区三区91| 成人免费av片| 亚洲一区二区毛片| 精品国产aⅴ麻豆| а√天堂8资源中文在线| 欧美va亚洲va| 国产在线观看免费视频今夜| 国产成人av一区二区三区在线观看| 中文字幕色一区二区| 免费视频观看成人| 最近日韩中文字幕中文| 亚洲视频久久久| 国产精品网站在线播放| 天天干天天操天天做| 国产高清欧美| 96精品久久久久中文字幕| av在线资源站| 色94色欧美sute亚洲线路二| 亚洲啪av永久无码精品放毛片| 先锋影音国产精品| 国产精品第100页| 青草久久伊人| 一本色道亚洲精品aⅴ| 37p粉嫩大胆色噜噜噜| 日韩有码一区二区三区| 久久综合福利| 蜜桃视频在线观看免费视频| 亚洲国产欧美一区| 偷偷操不一样的久久| 成人在线综合网| 人妻无码久久一区二区三区免费| 一区二区三区国产好| 欧美巨乳在线观看| 亚洲成人777777| 一区二区三区四区在线播放| 中文字幕 欧美 日韩| 国产精品激情| 久久久久久久有限公司| 国产伦精品一区二区三区视频金莲| 精品伊人久久97| 激情五月婷婷网| 日本一二三不卡| 一区二区久久精品| 韩国在线一区| 日韩久久久久久久久久久久久| 91p九色成人| 色综合影院在线| 国产三级在线观看视频| 亚洲高清免费观看 | 日韩av黄色| 久久精品视频在线观看| 高清一区二区三区四区| 欧美日韩国产一区二区三区| 中文字幕成人动漫| 国产1区2区3区精品美女| 欧美三级一级片| 日韩中文在线电影| www日韩av| gogo高清在线播放免费| 在线中文字幕日韩| 一区二区三区在线免费观看视频| 亚洲黄色小视频| 精品人妻无码一区二区三区 | 91tv官网精品成人亚洲| 精品不卡在线| 欧美成a人片免费观看久久五月天| 九九热r在线视频精品| 蝌蚪视频在线播放| 日韩精品自拍偷拍| 免费看一级视频| 亚洲福利一区二区| 免费在线观看a视频| 国产不卡视频一区| www.色偷偷.com| 日韩午夜av| 国产高清精品软男同| 日韩最新在线| 91原创国产| 丝袜美腿一区| 97av视频在线| a免费在线观看| 一本一本久久a久久精品综合小说| 国产av一区二区三区| 欧美视频一区在线| 国产精品99精品| 国产精品国产成人国产三级| 免费a v网站| 国产真实乱子伦精品视频| 美女网站免费观看视频| 黄色日韩在线| 综合久久国产| 成人在线免费观看网站| 日韩精品av一区二区三区| 国产毛片精品| 99中文字幕| 高清国产一区二区三区四区五区| 国产精品亚洲激情| 成人性教育av免费网址| 韩国v欧美v日本v亚洲| 天堂亚洲精品| 日韩在线视频一区| 日本美女高清在线观看免费| 亚洲人成在线观看网站高清| 天天插天天干天天操| 欧美日本乱大交xxxxx| 中文天堂在线播放| 欧洲av在线精品| 黄色av一级片| 懂色av中文一区二区三区天美| 国产成人精品片| 亚洲电影在线播放| 久久免费播放视频| 亚洲资源在线观看| 在线观看亚洲欧美| 欧美日韩亚洲高清| 国产免费av一区| 色综合久久中文综合久久牛| 日本中文字幕在线观看视频| 色综合天天狠狠| 波多野结衣爱爱| 欧美综合久久久| 91九色蝌蚪91por成人| 欧美色图12p| 艳妇乳肉豪妇荡乳av| 欧美卡1卡2卡| 丰满人妻一区二区三区免费| 亚洲精品一区二区三区影院| 六月婷婷中文字幕| 亚洲国产精品嫩草影院久久| 青青操视频在线| 一区二区三区动漫| 色多多视频在线观看| 美女福利精品视频| 在线视频cao| 国产精品久久久精品| 成人精品国产亚洲| 成人在线激情视频| 精品国产导航| 欧美欧美一区二区| 日韩精品一区二区三区免费观看| 亚洲精品一区二区三| 欧美影院一区| 欧美精品一区免费| 日韩电影网1区2区| 美女黄色片视频| 国产精品影视网| 亚洲男人在线天堂| 日本一区二区三区久久久久久久久不| 精品无码人妻一区| 亚洲乱码精品一二三四区日韩在线| 欧美成人国产精品高潮| 午夜亚洲福利老司机| 成人毛片在线播放| 91精品国产91久久久久久一区二区| www.香蕉视频| 亚洲欧美一区二区三区久久| 第一页在线观看| 久久久久久久久亚洲| 综合在线影院| 91福利视频导航| 色呦哟—国产精品| 无码熟妇人妻av在线电影| 美女尤物久久精品| 向日葵污视频在线观看| www.日韩精品| 日韩免费av一区| 天天影视涩香欲综合网| 国产乱码精品一区二区三区精东| 精品国产一区二区三区久久影院| 亚洲精品911| 一区二区三区无码高清视频| а天堂中文在线官网| 欧美专区在线视频| 国产伦理久久久久久妇女| 一本色道久久综合亚洲精品婷婷| 影音先锋国产精品| 9l视频白拍9色9l视频| www.亚洲国产| 久久久久人妻一区精品色欧美| 色婷婷综合中文久久一本| 亚洲av无码乱码国产麻豆 | 国产欧美 在线欧美| 国产精品国产| 国产免费一区二区视频| 麻豆精品在线视频| 国产 中文 字幕 日韩 在线| 亚洲天天做日日做天天谢日日欢| 最近中文字幕在线免费观看| 亚洲精品一区二区三区四区高清 | 成人动漫精品一区二区| 精品国产乱码久久久久久鸭王1| 色噜噜狠狠色综合中国| 欧美 日韩 国产 成人 在线| 美女av一区二区| 亚洲老司机网| 色一情一乱一伦一区二区三区 | 精品久久久久久久久久久久久久久久| 777精品伊人久久久久大香线蕉| 国产精品麻豆一区二区三区| 88xx成人精品| 国产日韩三级| 福利视频一区二区三区四区| 国产成a人亚洲精| 天堂网avav| 日韩欧美亚洲另类制服综合在线 | 日本美女久久| 先锋影音亚洲资源| 久久久久国产精品午夜一区| 中文字幕在线播放一区| 午夜精品久久久久久久| 高潮一区二区三区乱码| 欧美精品videossex88| 日韩欧美中文字幕一区二区三区 | 亚洲伦伦在线| 成年人小视频在线观看| 亚洲国产欧美在线| 欧美自拍偷拍第一页| 久久久日本电影| 精品视频在线你懂得| 男人日女人逼逼| 91视视频在线直接观看在线看网页在线看| 欧美日韩中文视频| 日韩精品免费电影| jk漫画禁漫成人入口| 欧美下载看逼逼| 九一久久久久久| 91高清免费看| 日韩欧美电影一区| 在线免费观看污| 久久国产精品亚洲va麻豆| 国产欧美日本| 久久久久久国产精品无码| 欧美亚洲一区二区在线| 在线观看麻豆蜜桃| 91久久在线观看| 欧美freesex交免费视频| 在线观看免费视频黄| 欧美色另类天堂2015| 日本黄色一区二区三区| 国产精品吊钟奶在线| 亚洲精品成人无限看| 在线观看成人动漫| 91久久一区二区| 日本中文字幕在线看| 91在线视频一区| 免费永久网站黄欧美| 精品人伦一区二区| 欧美一区二区在线免费播放| 丁香影院在线| 日韩欧美亚洲v片| 国内精品伊人久久久久av一坑| 日本网站在线免费观看| 亚洲情综合五月天| 成人网av.com/| 任你操这里只有精品| 综合婷婷亚洲小说| 五月婷婷丁香六月|