日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

b站黑马springCloud-常见面试题,多多三连

發(fā)布時(shí)間:2023/12/31 编程问答 72 豆豆
生活随笔 收集整理的這篇文章主要介紹了 b站黑马springCloud-常见面试题,多多三连 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

常見面試題

1.微服務(wù)篇

1.1.SpringCloud常見組件有哪些?

問題說明:這個(gè)題目主要考察對(duì)SpringCloud的組件基本了解

難易程度:簡(jiǎn)單

參考話術(shù)

SpringCloud包含的組件很多,有很多功能是重復(fù)的。其中最常用組件包括:

?注冊(cè)中心組件:Eureka、Nacos等

?負(fù)載均衡組件:Ribbon

?遠(yuǎn)程調(diào)用組件:OpenFeign

?網(wǎng)關(guān)組件:Zuul、Gateway

?服務(wù)保護(hù)組件:Hystrix、Sentinel

?服務(wù)配置管理組件:SpringCloudConfig、Nacos

1.2.Nacos的服務(wù)注冊(cè)表結(jié)構(gòu)是怎樣的?

問題說明:考察對(duì)Nacos數(shù)據(jù)分級(jí)結(jié)構(gòu)的了解,以及Nacos源碼的掌握情況

難易程度:一般

參考話術(shù)

Nacos采用了數(shù)據(jù)的分級(jí)存儲(chǔ)模型,最外層是Namespace,用來隔離環(huán)境。然后是Group,用來對(duì)服務(wù)分組。接下來就是服務(wù)(Service)了,一個(gè)服務(wù)包含多個(gè)實(shí)例,但是可能處于不同機(jī)房,因此Service下有多個(gè)集群(Cluster),Cluster下是不同的實(shí)例(Instance)。

對(duì)應(yīng)到Java代碼中,Nacos采用了一個(gè)多層的Map來表示。結(jié)構(gòu)為Map<String, Map<String, Service>>,其中最外層Map的key就是namespaceId,值是一個(gè)Map。內(nèi)層Map的key是group拼接serviceName,值是Service對(duì)象。Service對(duì)象內(nèi)部又是一個(gè)Map,key是集群名稱,值是Cluster對(duì)象。而Cluster對(duì)象內(nèi)部維護(hù)了Instance的集合。

如圖:

?

1.3.Nacos如何支撐阿里內(nèi)部數(shù)十萬服務(wù)注冊(cè)壓力?

問題說明:考察對(duì)Nacos源碼的掌握情況 (異步實(shí)現(xiàn))

難易程度:難

參考話術(shù)

Nacos內(nèi)部接收到注冊(cè)的請(qǐng)求時(shí),不會(huì)立即寫數(shù)據(jù),而是將服務(wù)注冊(cè)的任務(wù)放入一個(gè)阻塞隊(duì)列就立即響應(yīng)給客戶端(由于是阻塞隊(duì)列,所以只有隊(duì)列中有任務(wù)時(shí),task才會(huì)被執(zhí)行,沒有時(shí)task會(huì)等待,線程釋放CPU執(zhí)行權(quán))。然后利用線程池讀取阻塞隊(duì)列中的任務(wù),異步來完成實(shí)例更新,從而提高并發(fā)寫能力。

1.4.Nacos如何避免并發(fā)讀寫沖突問題?

問題說明:考察對(duì)Nacos源碼的掌握情況

難易程度:難

參考話術(shù)

Nacos在更新實(shí)例列表時(shí),會(huì)采用CopyOnWrite技術(shù),首先將舊的實(shí)例列表拷貝一份,然后更新拷貝的實(shí)例列表,再用更新后的實(shí)例列表來覆蓋舊的實(shí)例列表。

這樣在更新的過程中,就不會(huì)對(duì)讀實(shí)例列表的請(qǐng)求產(chǎn)生影響,也不會(huì)出現(xiàn)臟讀問題了。

1.5.Nacos與Eureka的區(qū)別有哪些?

問題說明:考察對(duì)Nacos、Eureka的底層實(shí)現(xiàn)的掌握情況

難易程度:難

參考話術(shù)

Nacos與Eureka有相同點(diǎn),也有不同之處,可以從以下幾點(diǎn)來描述:

  • 接口方式:Nacos與Eureka都對(duì)外暴露了Rest風(fēng)格的API接口,用來實(shí)現(xiàn)服務(wù)注冊(cè)、發(fā)現(xiàn)等功能

  • 實(shí)例類型:Nacos的實(shí)例有永久和臨時(shí)實(shí)例之分;而Eureka只支持臨時(shí)實(shí)例

  • 健康檢測(cè):Nacos對(duì)臨時(shí)實(shí)例采用心跳模式檢測(cè),對(duì)永久實(shí)例采用主動(dòng)請(qǐng)求來檢測(cè);Eureka只支持心跳模式

  • 服務(wù)發(fā)現(xiàn):Nacos支持定時(shí)拉取和訂閱推送兩種模式;Eureka只支持定時(shí)拉取模式

1.6.Sentinel的限流與Gateway的限流有什么差別?

問題說明:考察對(duì)限流算法的掌握情況

難易程度:難

參考話術(shù)

限流算法常見的有三種實(shí)現(xiàn):滑動(dòng)時(shí)間窗口、令牌桶算法、漏桶算法。Gateway則采用了基于Redis實(shí)現(xiàn)的令牌桶算法。

而Sentinel內(nèi)部卻比較復(fù)雜:

  • 默認(rèn)限流模式是基于滑動(dòng)時(shí)間窗口算法

  • 排隊(duì)等待的限流模式則基于漏桶算法

  • 而熱點(diǎn)參數(shù)限流則是基于令牌桶算法

1.7.Sentinel的線程隔離與Hystix的線程隔離有什么差別?

問題說明:考察對(duì)線程隔離方案的掌握情況

難易程度:一般

參考話術(shù)

Hystix默認(rèn)是基于線程池實(shí)現(xiàn)的線程隔離,每一個(gè)被隔離的業(yè)務(wù)都要?jiǎng)?chuàng)建一個(gè)獨(dú)立的線程池,線程過多會(huì)帶來額外的CPU開銷,性能一般,但是隔離性更強(qiáng)。

Sentinel是基于信號(hào)量(計(jì)數(shù)器)實(shí)現(xiàn)的線程隔離,不用創(chuàng)建線程池,性能較好,但是隔離性一般。

2.MQ篇

2.1.你們?yōu)槭裁催x擇了RabbitMQ而不是其它的MQ?

如圖:

?

話術(shù):

kafka是以吞吐量高而聞名,不過其數(shù)據(jù)穩(wěn)定性一般,而且無法保證消息有序性。我們公司的日志收集也有使用,業(yè)務(wù)模塊中則使用的RabbitMQ。

阿里巴巴的RocketMQ基于Kafka的原理,彌補(bǔ)了Kafka的缺點(diǎn),繼承了其高吞吐的優(yōu)勢(shì),其客戶端目前以Java為主。但是我們擔(dān)心阿里巴巴開源產(chǎn)品的穩(wěn)定性,所以就沒有使用。

RabbitMQ基于面向并發(fā)的語(yǔ)言Erlang開發(fā),吞吐量不如Kafka,但是對(duì)我們公司來講夠用了。而且消息可靠性較好,并且消息延遲極低,集群搭建比較方便。支持多種協(xié)議,并且有各種語(yǔ)言的客戶端,比較靈活。Spring對(duì)RabbitMQ的支持也比較好,使用起來比較方便,比較符合我們公司的需求。

綜合考慮我們公司的并發(fā)需求以及穩(wěn)定性需求,我們選擇了RabbitMQ。

2.2.RabbitMQ如何確保消息的不丟失?

話術(shù):

RabbitMQ針對(duì)消息傳遞過程中可能發(fā)生問題的各個(gè)地方,給出了針對(duì)性的解決方案:

  • 生產(chǎn)者發(fā)送消息時(shí)可能因?yàn)榫W(wǎng)絡(luò)問題導(dǎo)致消息沒有到達(dá)交換機(jī):

    • RabbitMQ提供了publisher confirm機(jī)制

      • 生產(chǎn)者發(fā)送消息后,可以編寫ConfirmCallback函數(shù)

      • 消息成功到達(dá)交換機(jī)后,RabbitMQ會(huì)調(diào)用ConfirmCallback通知消息的發(fā)送者,返回ACK

      • 消息如果未到達(dá)交換機(jī),RabbitMQ也會(huì)調(diào)用ConfirmCallback通知消息的發(fā)送者,返回NACK

      • 消息超時(shí)未發(fā)送成功也會(huì)拋出異常

  • 消息到達(dá)交換機(jī)后,如果未能到達(dá)隊(duì)列,也會(huì)導(dǎo)致消息丟失:

    • RabbitMQ提供了publisher return機(jī)制

      • 生產(chǎn)者可以定義ReturnCallback函數(shù)

      • 消息到達(dá)交換機(jī),未到達(dá)隊(duì)列,RabbitMQ會(huì)調(diào)用ReturnCallback通知發(fā)送者,告知失敗原因

  • 消息到達(dá)隊(duì)列后,MQ宕機(jī)也可能導(dǎo)致丟失消息:

    • RabbitMQ提供了持久化功能,集群的主從備份功能

      • 消息持久化,RabbitMQ會(huì)將交換機(jī)、隊(duì)列、消息持久化到磁盤,宕機(jī)重啟可以恢復(fù)消息

      • 鏡像集群,仲裁隊(duì)列,都可以提供主從備份功能,主節(jié)點(diǎn)宕機(jī),從節(jié)點(diǎn)會(huì)自動(dòng)切換為主,數(shù)據(jù)依然在

  • 消息投遞給消費(fèi)者后,如果消費(fèi)者處理不當(dāng),也可能導(dǎo)致消息丟失

    • SpringAMQP基于RabbitMQ提供了消費(fèi)者確認(rèn)機(jī)制、消費(fèi)者重試機(jī)制,消費(fèi)者失敗處理策略:

      • 消費(fèi)者的確認(rèn)機(jī)制:

        • 消費(fèi)者處理消息成功,未出現(xiàn)異常時(shí),Spring返回ACK給RabbitMQ,消息才被移除

        • 消費(fèi)者處理消息失敗,拋出異常,宕機(jī),Spring返回NACK或者不返回結(jié)果,消息不被異常

      • 消費(fèi)者重試機(jī)制:

        • 默認(rèn)情況下,消費(fèi)者處理失敗時(shí),消息會(huì)再次回到MQ隊(duì)列,然后投遞給其它消費(fèi)者。Spring提供的消費(fèi)者重試機(jī)制,則是在處理失敗后不返回NACK,而是直接在消費(fèi)者本地重試。多次重試都失敗后,則按照消費(fèi)者失敗處理策略來處理消息。避免了消息頻繁入隊(duì)帶來的額外壓力。

      • 消費(fèi)者失敗策略:

        • 當(dāng)消費(fèi)者多次本地重試失敗時(shí),消息默認(rèn)會(huì)丟棄。

        • Spring提供了Republish策略,在多次重試都失敗,耗盡重試次數(shù)后,將消息重新投遞給指定的異常交換機(jī),并且會(huì)攜帶上異常棧信息,幫助定位問題。

2.3.RabbitMQ如何避免消息堆積?

話術(shù):

消息堆積問題產(chǎn)生的原因往往是因?yàn)橄l(fā)送的速度超過了消費(fèi)者消息處理的速度。因此解決方案無外乎以下三點(diǎn):

  • 提高消費(fèi)者處理速度

  • 增加更多消費(fèi)者

  • 增加隊(duì)列消息存儲(chǔ)上限

1)提高消費(fèi)者處理速度

消費(fèi)者處理速度是由業(yè)務(wù)代碼決定的,所以我們能做的事情包括:

  • 盡可能優(yōu)化業(yè)務(wù)代碼,提高業(yè)務(wù)性能

  • 接收到消息后,開啟線程池,并發(fā)處理多個(gè)消息

優(yōu)點(diǎn):成本低,改改代碼即可

缺點(diǎn):開啟線程池會(huì)帶來額外的性能開銷,對(duì)于高頻、低時(shí)延的任務(wù)不合適。推薦任務(wù)執(zhí)行周期較長(zhǎng)的業(yè)務(wù)。

2)增加更多消費(fèi)者

一個(gè)隊(duì)列綁定多個(gè)消費(fèi)者,共同爭(zhēng)搶任務(wù),自然可以提供消息處理的速度。

優(yōu)點(diǎn):能用錢解決的問題都不是問題。實(shí)現(xiàn)簡(jiǎn)單粗暴

缺點(diǎn):問題是沒有錢。成本太高

3)增加隊(duì)列消息存儲(chǔ)上限

在RabbitMQ的1.8版本后,加入了新的隊(duì)列模式:Lazy Queue

這種隊(duì)列不會(huì)將消息保存在內(nèi)存中,而是在收到消息后直接寫入磁盤中,理論上沒有存儲(chǔ)上限。可以解決消息堆積問題。

優(yōu)點(diǎn):磁盤存儲(chǔ)更安全;存儲(chǔ)無上限;避免內(nèi)存存儲(chǔ)帶來的Page Out問題,性能更穩(wěn)定;

缺點(diǎn):磁盤存儲(chǔ)受到IO性能的限制,消息時(shí)效性不如內(nèi)存模式,但影響不大。

2.4.RabbitMQ如何保證消息的有序性?

話術(shù):

其實(shí)RabbitMQ是隊(duì)列存儲(chǔ),天然具備先進(jìn)先出的特點(diǎn),只要消息的發(fā)送是有序的,那么理論上接收也是有序的。不過當(dāng)一個(gè)隊(duì)列綁定了多個(gè)消費(fèi)者時(shí),可能出現(xiàn)消息輪詢投遞給消費(fèi)者的情況,而消費(fèi)者的處理順序就無法保證了。

因此,要保證消息的有序性,需要做的下面幾點(diǎn):

  • 保證消息發(fā)送的有序性

  • 保證一組有序的消息都發(fā)送到同一個(gè)隊(duì)列

  • 保證一個(gè)隊(duì)列只包含一個(gè)消費(fèi)者

2.5.如何防止MQ消息被重復(fù)消費(fèi)?

話術(shù):

消息重復(fù)消費(fèi)的原因多種多樣,不可避免。所以只能從消費(fèi)者端入手,只要能保證消息處理的冪等性就可以確保消息不被重復(fù)消費(fèi)。

而冪等性的保證又有很多方案:

  • 給每一條消息都添加一個(gè)唯一id,在本地記錄消息表及消息狀態(tài),處理消息時(shí)基于數(shù)據(jù)庫(kù)表的id唯一性做判斷

  • 同樣是記錄消息表,利用消息狀態(tài)字段實(shí)現(xiàn)基于樂觀鎖的判斷,保證冪等

  • 基于業(yè)務(wù)本身的冪等性。比如根據(jù)id的刪除、查詢業(yè)務(wù)天生冪等;新增、修改等業(yè)務(wù)可以考慮基于數(shù)據(jù)庫(kù)id唯一性、或者樂觀鎖機(jī)制確保冪等。本質(zhì)與消息表方案類似。

2.6.如何保證RabbitMQ的高可用?

話術(shù):

要實(shí)現(xiàn)RabbitMQ的高可用無外乎下面兩點(diǎn):

  • 做好交換機(jī)、隊(duì)列、消息的持久化

  • 搭建RabbitMQ的鏡像集群,做好主從備份。當(dāng)然也可以使用仲裁隊(duì)列代替鏡像集群。

2.7.使用MQ可以解決那些問題?

話術(shù):

RabbitMQ能解決的問題很多,例如:

  • 解耦合:將幾個(gè)業(yè)務(wù)關(guān)聯(lián)的微服務(wù)調(diào)用修改為基于MQ的異步通知,可以解除微服務(wù)之間的業(yè)務(wù)耦合。同時(shí)還提高了業(yè)務(wù)性能。

  • 流量削峰:將突發(fā)的業(yè)務(wù)請(qǐng)求放入MQ中,作為緩沖區(qū)。后端的業(yè)務(wù)根據(jù)自己的處理能力從MQ中獲取消息,逐個(gè)處理任務(wù)。流量曲線變的平滑很多

  • 延遲隊(duì)列:基于RabbitMQ的死信隊(duì)列或者DelayExchange插件,可以實(shí)現(xiàn)消息發(fā)送后,延遲接收的效果。

3.Redis篇

3.1.Redis與Memcache的區(qū)別?

  • redis支持更豐富的數(shù)據(jù)類型(支持更復(fù)雜的應(yīng)用場(chǎng)景):Redis不僅僅支持簡(jiǎn)單的k/v類型的數(shù)據(jù),同時(shí)還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。memcache支持簡(jiǎn)單的數(shù)據(jù)類型,String。

  • Redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤中,重啟的時(shí)候可以再次加載進(jìn)行使用,而Memecache把數(shù)據(jù)全部存在內(nèi)存之中。

  • 集群模式:memcached沒有原生的集群模式,需要依靠客戶端來實(shí)現(xiàn)往集群中分片寫入數(shù)據(jù);但是 redis 目前是原生支持 cluster 模式的.

  • Redis使用單線程:Memcached是多線程,非阻塞IO復(fù)用的網(wǎng)絡(luò)模型;Redis使用單線程的多路 IO 復(fù)用模型。

?

3.2.Redis的單線程問題

面試官:Redis采用單線程,如何保證高并發(fā)?

面試話術(shù)

Redis快的主要原因是:

  • 完全基于內(nèi)存

  • 數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)單,對(duì)數(shù)據(jù)操作也簡(jiǎn)單

  • 使用多路 I/O 復(fù)用模型,充分利用CPU資源

  • 面試官:這樣做的好處是什么?

    面試話術(shù)

    單線程優(yōu)勢(shì)有下面幾點(diǎn):

    • 代碼更清晰,處理邏輯更簡(jiǎn)單

    • 不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因?yàn)殒i而導(dǎo)致的性能消耗

    • 不存在多進(jìn)程或者多線程導(dǎo)致的CPU切換,充分利用CPU資源

    3.2.Redis的持久化方案由哪些?

    相關(guān)資料:

    1)RDB 持久化

    RDB持久化可以使用save或bgsave,為了不阻塞主進(jìn)程業(yè)務(wù),一般都使用bgsave,流程:

    • Redis 進(jìn)程會(huì) fork 出一個(gè)子進(jìn)程(與父進(jìn)程內(nèi)存數(shù)據(jù)一致)。

    • 父進(jìn)程繼續(xù)處理客戶端請(qǐng)求命令

    • 由子進(jìn)程將內(nèi)存中的所有數(shù)據(jù)寫入到一個(gè)臨時(shí)的 RDB 文件中。

    • 完成寫入操作之后,舊的 RDB 文件會(huì)被新的 RDB 文件替換掉。

    下面是一些和 RDB 持久化相關(guān)的配置:

    • save 60 10000:如果在 60 秒內(nèi)有 10000 個(gè) key 發(fā)生改變,那就執(zhí)行 RDB 持久化。

    • stop-writes-on-bgsave-error yes:如果 Redis 執(zhí)行 RDB 持久化失敗(常見于操作系統(tǒng)內(nèi)存不足),那么 Redis 將不再接受 client 寫入數(shù)據(jù)的請(qǐng)求。

    • rdbcompression yes:當(dāng)生成 RDB 文件時(shí),同時(shí)進(jìn)行壓縮。

    • dbfilename dump.rdb:將 RDB 文件命名為 dump.rdb。

    • dir /var/lib/redis:將 RDB 文件保存在/var/lib/redis目錄下。

      當(dāng)然在實(shí)踐中,我們通常會(huì)將stop-writes-on-bgsave-error設(shè)置為false,同時(shí)讓監(jiān)控系統(tǒng)在 Redis 執(zhí)行 RDB 持久化失敗時(shí)發(fā)送告警,以便人工介入解決,而不是粗暴地拒絕 client 的寫入請(qǐng)求。

    RDB持久化的優(yōu)點(diǎn):

    • RDB持久化文件小,Redis數(shù)據(jù)恢復(fù)時(shí)速度快

    • 子進(jìn)程不影響父進(jìn)程,父進(jìn)程可以持續(xù)處理客戶端命令

    • 子進(jìn)程fork時(shí)采用copy-on-write方式,大多數(shù)情況下,沒有太多的內(nèi)存消耗,效率比較好。

    RDB 持久化的缺點(diǎn):

    • 子進(jìn)程fork時(shí)采用copy-on-write方式,如果Redis此時(shí)寫操作較多,可能導(dǎo)致額外的內(nèi)存占用,甚至內(nèi)存溢出

    • RDB文件壓縮會(huì)減小文件體積,但通過時(shí)會(huì)對(duì)CPU有額外的消耗

    • 如果業(yè)務(wù)場(chǎng)景很看重?cái)?shù)據(jù)的持久性 (durability),那么不應(yīng)該采用 RDB 持久化。譬如說,如果 Redis 每 5 分鐘執(zhí)行一次 RDB 持久化,要是 Redis 意外奔潰了,那么最多會(huì)丟失 5 分鐘的數(shù)據(jù)。

    2)AOF 持久化

      可以使用appendonly yes配置項(xiàng)來開啟 AOF 持久化。Redis 執(zhí)行 AOF 持久化時(shí),會(huì)將接收到的寫命令追加到 AOF 文件的末尾,因此 Redis 只要對(duì) AOF 文件中的命令進(jìn)行回放,就可以將數(shù)據(jù)庫(kù)還原到原先的狀態(tài)。   與 RDB 持久化相比,AOF 持久化的一個(gè)明顯優(yōu)勢(shì)就是,它可以提高數(shù)據(jù)的持久性 (durability)。因?yàn)樵?AOF 模式下,Redis 每次接收到 client 的寫命令,就會(huì)將命令write()到 AOF 文件末尾。   然而,在 Linux 中,將數(shù)據(jù)write()到文件后,數(shù)據(jù)并不會(huì)立即刷新到磁盤,而會(huì)先暫存在 OS 的文件系統(tǒng)緩沖區(qū)。在合適的時(shí)機(jī),OS 才會(huì)將緩沖區(qū)的數(shù)據(jù)刷新到磁盤(如果需要將文件內(nèi)容刷新到磁盤,可以調(diào)用fsync()或fdatasync())。   通過appendfsync配置項(xiàng),可以控制 Redis 將命令同步到磁盤的頻率:

    • always:每次 Redis 將命令write()到 AOF 文件時(shí),都會(huì)調(diào)用fsync(),將命令刷新到磁盤。這可以保證最好的數(shù)據(jù)持久性,但卻會(huì)給系統(tǒng)帶來極大的開銷。

    • no:Redis 只將命令write()到 AOF 文件。這會(huì)讓 OS 決定何時(shí)將命令刷新到磁盤。

    • everysec:除了將命令write()到 AOF 文件,Redis 還會(huì)每秒執(zhí)行一次fsync()。在實(shí)踐中,推薦使用這種設(shè)置,一定程度上可以保證數(shù)據(jù)持久性,又不會(huì)明顯降低 Redis 性能。

      然而,AOF 持久化并不是沒有缺點(diǎn)的:Redis 會(huì)不斷將接收到的寫命令追加到 AOF 文件中,導(dǎo)致 AOF 文件越來越大。過大的 AOF 文件會(huì)消耗磁盤空間,并且導(dǎo)致 Redis 重啟時(shí)更加緩慢。為了解決這個(gè)問題,在適當(dāng)情況下,Redis 會(huì)對(duì) AOF 文件進(jìn)行重寫,去除文件中冗余的命令,以減小 AOF 文件的體積。在重寫 AOF 文件期間, Redis 會(huì)啟動(dòng)一個(gè)子進(jìn)程,由子進(jìn)程負(fù)責(zé)對(duì) AOF 文件進(jìn)行重寫。   可以通過下面兩個(gè)配置項(xiàng),控制 Redis 重寫 AOF 文件的頻率:

    • auto-aof-rewrite-min-size 64mb

    • auto-aof-rewrite-percentage 100

      上面兩個(gè)配置的作用:當(dāng) AOF 文件的體積大于 64MB,并且 AOF 文件的體積比上一次重寫之后的體積大了至少一倍,那么 Redis 就會(huì)執(zhí)行 AOF 重寫。

    優(yōu)點(diǎn):

    • 持久化頻率高,數(shù)據(jù)可靠性高

    • 沒有額外的內(nèi)存或CPU消耗

    缺點(diǎn):

    • 文件體積大

    • 文件大導(dǎo)致服務(wù)數(shù)據(jù)恢復(fù)時(shí)效率較低

    面試話術(shù):

    Redis 提供了兩種數(shù)據(jù)持久化的方式,一種是 RDB,另一種是 AOF。默認(rèn)情況下,Redis 使用的是 RDB 持久化。

    RDB持久化文件體積較小,但是保存數(shù)據(jù)的頻率一般較低,可靠性差,容易丟失數(shù)據(jù)。另外RDB寫數(shù)據(jù)時(shí)會(huì)采用Fork函數(shù)拷貝主進(jìn)程,可能有額外的內(nèi)存消耗,文件壓縮也會(huì)有額外的CPU消耗。

    ROF持久化可以做到每秒鐘持久化一次,可靠性高。但是持久化文件體積較大,導(dǎo)致數(shù)據(jù)恢復(fù)時(shí)讀取文件時(shí)間較長(zhǎng),效率略低

    3.3.Redis的集群方式有哪些?

    面試話術(shù):

    Redis集群可以分為主從集群分片集群兩類。

    主從集群一般一主多從,主庫(kù)用來寫數(shù)據(jù),從庫(kù)用來讀數(shù)據(jù)。結(jié)合哨兵,可以再主庫(kù)宕機(jī)時(shí)從新選主,目的是保證Redis的高可用

    分片集群是數(shù)據(jù)分片,我們會(huì)讓多個(gè)Redis節(jié)點(diǎn)組成集群,并將16383個(gè)插槽分到不同的節(jié)點(diǎn)上。存儲(chǔ)數(shù)據(jù)時(shí)利用對(duì)key做hash運(yùn)算,得到插槽值后存儲(chǔ)到對(duì)應(yīng)的節(jié)點(diǎn)即可。因?yàn)榇鎯?chǔ)數(shù)據(jù)面向的是插槽而非節(jié)點(diǎn)本身,因此可以做到集群動(dòng)態(tài)伸縮。目的是讓Redis能存儲(chǔ)更多數(shù)據(jù)。

    1)主從集群

    主從集群,也是讀寫分離集群。一般都是一主多從方式。

    Redis 的復(fù)制(replication)功能允許用戶根據(jù)一個(gè) Redis 服務(wù)器來創(chuàng)建任意多個(gè)該服務(wù)器的復(fù)制品,其中被復(fù)制的服務(wù)器為主服務(wù)器(master),而通過復(fù)制創(chuàng)建出來的服務(wù)器復(fù)制品則為從服務(wù)器(slave)。

    只要主從服務(wù)器之間的網(wǎng)絡(luò)連接正常,主從服務(wù)器兩者會(huì)具有相同的數(shù)據(jù),主服務(wù)器就會(huì)一直將發(fā)生在自己身上的數(shù)據(jù)更新同步 給從服務(wù)器,從而一直保證主從服務(wù)器的數(shù)據(jù)相同。

    • 寫數(shù)據(jù)時(shí)只能通過主節(jié)點(diǎn)完成

    • 讀數(shù)據(jù)可以從任何節(jié)點(diǎn)完成

    • 如果配置了哨兵節(jié)點(diǎn),當(dāng)master宕機(jī)時(shí),哨兵會(huì)從salve節(jié)點(diǎn)選出一個(gè)新的主。

    主從集群分兩種:

    ?

    ?帶有哨兵的集群:

    2)分片集群

    主從集群中,每個(gè)節(jié)點(diǎn)都要保存所有信息,容易形成木桶效應(yīng)。并且當(dāng)數(shù)據(jù)量較大時(shí),單個(gè)機(jī)器無法滿足需求。此時(shí)我們就要使用分片集群了。

    ?

    集群特征:

    • 每個(gè)節(jié)點(diǎn)都保存不同數(shù)據(jù)

    • 所有的redis節(jié)點(diǎn)彼此互聯(lián)(PING-PONG機(jī)制),內(nèi)部使用二進(jìn)制協(xié)議優(yōu)化傳輸速度和帶寬.

    • 節(jié)點(diǎn)的fail是通過集群中超過半數(shù)的節(jié)點(diǎn)檢測(cè)失效時(shí)才生效.

    • 客戶端與redis節(jié)點(diǎn)直連,不需要中間proxy層連接集群中任何一個(gè)可用節(jié)點(diǎn)都可以訪問到數(shù)據(jù)

    • redis-cluster把所有的物理節(jié)點(diǎn)映射到[0-16383]slot(插槽)上,實(shí)現(xiàn)動(dòng)態(tài)伸縮

    為了保證Redis中每個(gè)節(jié)點(diǎn)的高可用,我們還可以給每個(gè)節(jié)點(diǎn)創(chuàng)建replication(slave節(jié)點(diǎn)),如圖:

    ?出現(xiàn)故障時(shí),主從可以及時(shí)切換:

    ?

    3.4.Redis的常用數(shù)據(jù)類型有哪些?

    支持多種類型的數(shù)據(jù)結(jié)構(gòu),主要區(qū)別是value存儲(chǔ)的數(shù)據(jù)格式不同:

    • string:最基本的數(shù)據(jù)類型,二進(jìn)制安全的字符串,最大512M。

    • list:按照添加順序保持順序的字符串列表。

    • set:無序的字符串集合,不存在重復(fù)的元素。

    • sorted set:已排序的字符串集合。

    • hash:key-value對(duì)格式

    3.5.聊一下Redis事務(wù)機(jī)制

    相關(guān)資料:

    參考:事務(wù)(transaction) — Redis 命令參考

    Redis事務(wù)功能是通過MULTI、EXEC、DISCARD和WATCH 四個(gè)原語(yǔ)實(shí)現(xiàn)的。Redis會(huì)將一個(gè)事務(wù)中的所有命令序列化,然后按順序執(zhí)行。但是Redis事務(wù)不支持回滾操作,命令運(yùn)行出錯(cuò)后,正確的命令會(huì)繼續(xù)執(zhí)行。

    • MULTI: 用于開啟一個(gè)事務(wù),它總是返回OK。 MULTI執(zhí)行之后,客戶端可以繼續(xù)向服務(wù)器發(fā)送任意多條命令,這些命令不會(huì)立即被執(zhí)行,而是被放到一個(gè)待執(zhí)行命令隊(duì)列

    • EXEC:按順序執(zhí)行命令隊(duì)列內(nèi)的所有命令。返回所有命令的返回值。事務(wù)執(zhí)行過程中,Redis不會(huì)執(zhí)行其它事務(wù)的命令。

    • DISCARD:清空命令隊(duì)列,并放棄執(zhí)行事務(wù), 并且客戶端會(huì)從事務(wù)狀態(tài)中退出

    • WATCH:Redis的樂觀鎖機(jī)制,利用compare-and-set(CAS)原理,可以監(jiān)控一個(gè)或多個(gè)鍵,一旦其中有一個(gè)鍵被修改,之后的事務(wù)就不會(huì)執(zhí)行

    使用事務(wù)時(shí)可能會(huì)遇上以下兩種錯(cuò)誤:

    • 執(zhí)行 EXEC 之前,入隊(duì)的命令可能會(huì)出錯(cuò)。比如說,命令可能會(huì)產(chǎn)生語(yǔ)法錯(cuò)誤(參數(shù)數(shù)量錯(cuò)誤,參數(shù)名錯(cuò)誤,等等),或者其他更嚴(yán)重的錯(cuò)誤,比如內(nèi)存不足(如果服務(wù)器使用 maxmemory 設(shè)置了最大內(nèi)存限制的話)。

      • Redis 2.6.5 開始,服務(wù)器會(huì)對(duì)命令入隊(duì)失敗的情況進(jìn)行記錄,并在客戶端調(diào)用 EXEC 命令時(shí),拒絕執(zhí)行并自動(dòng)放棄這個(gè)事務(wù)。

    • 命令可能在 EXEC 調(diào)用之后失敗。舉個(gè)例子,事務(wù)中的命令可能處理了錯(cuò)誤類型的鍵,比如將列表命令用在了字符串鍵上面,諸如此類。

      • 即使事務(wù)中有某個(gè)/某些命令在執(zhí)行時(shí)產(chǎn)生了錯(cuò)誤, 事務(wù)中的其他命令仍然會(huì)繼續(xù)執(zhí)行,不會(huì)回滾。

    為什么 Redis 不支持回滾(roll back)?

    以下是這種做法的優(yōu)點(diǎn):

    • Redis 命令只會(huì)因?yàn)殄e(cuò)誤的語(yǔ)法而失敗(并且這些問題不能在入隊(duì)時(shí)發(fā)現(xiàn)),或是命令用在了錯(cuò)誤類型的鍵上面:這也就是說,從實(shí)用性的角度來說,失敗的命令是由編程錯(cuò)誤造成的,而這些錯(cuò)誤應(yīng)該在開發(fā)的過程中被發(fā)現(xiàn),而不應(yīng)該出現(xiàn)在生產(chǎn)環(huán)境中。

    • 因?yàn)椴恍枰獙?duì)回滾進(jìn)行支持,所以 Redis 的內(nèi)部可以保持簡(jiǎn)單且快速。

    鑒于沒有任何機(jī)制能避免程序員自己造成的錯(cuò)誤, 并且這類錯(cuò)誤通常不會(huì)在生產(chǎn)環(huán)境中出現(xiàn), 所以 Redis 選擇了更簡(jiǎn)單、更快速的無回滾方式來處理事務(wù)。

    面試話術(shù):

    Redis事務(wù)其實(shí)是把一系列Redis命令放入隊(duì)列,然后批量執(zhí)行,執(zhí)行過程中不會(huì)有其它事務(wù)來打斷。不過與關(guān)系型數(shù)據(jù)庫(kù)的事務(wù)不同,Redis事務(wù)不支持回滾操作,事務(wù)中某個(gè)命令執(zhí)行失敗,其它命令依然會(huì)執(zhí)行。

    為了彌補(bǔ)不能回滾的問題,Redis會(huì)在事務(wù)入隊(duì)時(shí)就檢查命令,如果命令異常則會(huì)放棄整個(gè)事務(wù)。

    因此,只要程序員編程是正確的,理論上說Redis會(huì)正確執(zhí)行所有事務(wù),無需回滾。

    面試官:如果事務(wù)執(zhí)行一半的時(shí)候Redis宕機(jī)怎么辦?

    Redis有持久化機(jī)制,因?yàn)榭煽啃詥栴},我們一般使用AOF持久化。事務(wù)的所有命令也會(huì)寫入AOF文件,但是如果在執(zhí)行EXEC命令之前,Redis已經(jīng)宕機(jī),則AOF文件中事務(wù)不完整。使用 redis-check-aof 程序可以移除 AOF 文件中不完整事務(wù)的信息,確保服務(wù)器可以順利啟動(dòng)。

    3.6.Redis的Key過期策略

    參考資料:

    為什么需要內(nèi)存回收?

    • 1、在Redis中,set指令可以指定key的過期時(shí)間,當(dāng)過期時(shí)間到達(dá)以后,key就失效了;

    • 2、Redis是基于內(nèi)存操作的,所有的數(shù)據(jù)都是保存在內(nèi)存中,一臺(tái)機(jī)器的內(nèi)存是有限且很寶貴的。

    基于以上兩點(diǎn),為了保證Redis能繼續(xù)提供可靠的服務(wù),Redis需要一種機(jī)制清理掉不常用的、無效的、多余的數(shù)據(jù),失效后的數(shù)據(jù)需要及時(shí)清理,這就需要內(nèi)存回收了。

    Redis的內(nèi)存回收主要分為過期刪除策略和內(nèi)存淘汰策略兩部分。

    過期刪除策略

    刪除達(dá)到過期時(shí)間的key。

    • 1)定時(shí)刪除

    對(duì)于每一個(gè)設(shè)置了過期時(shí)間的key都會(huì)創(chuàng)建一個(gè)定時(shí)器,一旦到達(dá)過期時(shí)間就立即刪除。該策略可以立即清除過期的數(shù)據(jù),對(duì)內(nèi)存較友好,但是缺點(diǎn)是占用了大量的CPU資源去處理過期的數(shù)據(jù),會(huì)影響Redis的吞吐量和響應(yīng)時(shí)間。

    • 2)惰性刪除

    當(dāng)訪問一個(gè)key時(shí),才判斷該key是否過期,過期則刪除。該策略能最大限度地節(jié)省CPU資源,但是對(duì)內(nèi)存卻十分不友好。有一種極端的情況是可能出現(xiàn)大量的過期key沒有被再次訪問,因此不會(huì)被清除,導(dǎo)致占用了大量的內(nèi)存。

    在計(jì)算機(jī)科學(xué)中,懶惰刪除(英文:lazy deletion)指的是從一個(gè)散列表(也稱哈希表)中刪除元素的一種方法。在這個(gè)方法中,刪除僅僅是指標(biāo)記一個(gè)元素被刪除,而不是整個(gè)清除它。被刪除的位點(diǎn)在插入時(shí)被當(dāng)作空元素,在搜索之時(shí)被當(dāng)作已占據(jù)。

    • 3)定期刪除

    每隔一段時(shí)間,掃描Redis中過期key字典,并清除部分過期的key。該策略是前兩者的一個(gè)折中方案,還可以通過調(diào)整定時(shí)掃描的時(shí)間間隔和每次掃描的限定耗時(shí),在不同情況下使得CPU和內(nèi)存資源達(dá)到最優(yōu)的平衡效果。

    在Redis中,同時(shí)使用了定期刪除和惰性刪除。不過Redis定期刪除采用的是隨機(jī)抽取的方式刪除部分Key,因此不能保證過期key 100%的刪除。

    Redis結(jié)合了定期刪除和惰性刪除,基本上能很好的處理過期數(shù)據(jù)的清理,但是實(shí)際上還是有點(diǎn)問題的,如果過期key較多,定期刪除漏掉了一部分,而且也沒有及時(shí)去查,即沒有走惰性刪除,那么就會(huì)有大量的過期key堆積在內(nèi)存中,導(dǎo)致redis內(nèi)存耗盡,當(dāng)內(nèi)存耗盡之后,有新的key到來會(huì)發(fā)生什么事呢?是直接拋棄還是其他措施呢?有什么辦法可以接受更多的key?

    內(nèi)存淘汰策略

    Redis的內(nèi)存淘汰策略,是指內(nèi)存達(dá)到maxmemory極限時(shí),使用某種算法來決定清理掉哪些數(shù)據(jù),以保證新數(shù)據(jù)的存入。

    Redis的內(nèi)存淘汰機(jī)制包括:

    • noeviction: 當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),新寫入操作會(huì)報(bào)錯(cuò)。

    • allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間(server.db[i].dict)中,移除最近最少使用的 key(這個(gè)是最常用的)。

    • allkeys-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間(server.db[i].dict)中,隨機(jī)移除某個(gè) key。

    • volatile-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間(server.db[i].expires)中,移除最近最少使用的 key。

    • volatile-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間(server.db[i].expires)中,隨機(jī)移除某個(gè) key。

    • volatile-ttl:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間(server.db[i].expires)中,有更早過期時(shí)間的 key 優(yōu)先移除。

    在配置文件中,通過maxmemory-policy可以配置要使用哪一個(gè)淘汰機(jī)制。

    什么時(shí)候會(huì)進(jìn)行淘汰?

    Redis會(huì)在每一次處理命令的時(shí)候(processCommand函數(shù)調(diào)用freeMemoryIfNeeded)判斷當(dāng)前redis是否達(dá)到了內(nèi)存的最大限制,如果達(dá)到限制,則使用對(duì)應(yīng)的算法去處理需要?jiǎng)h除的key。

    在淘汰key時(shí),Redis默認(rèn)最常用的是LRU算法(Latest Recently Used)。Redis通過在每一個(gè)redisObject保存lru屬性來保存key最近的訪問時(shí)間,在實(shí)現(xiàn)LRU算法時(shí)直接讀取key的lru屬性。

    具體實(shí)現(xiàn)時(shí),Redis遍歷每一個(gè)db,從每一個(gè)db中隨機(jī)抽取一批樣本key,默認(rèn)是3個(gè)key,再?gòu)倪@3個(gè)key中,刪除最近最少使用的key。

    面試話術(shù):

    Redis過期策略包含定期刪除和惰性刪除兩部分。定期刪除是在Redis內(nèi)部有一個(gè)定時(shí)任務(wù),會(huì)定期刪除一些過期的key。惰性刪除是當(dāng)用戶查詢某個(gè)Key時(shí),會(huì)檢查這個(gè)Key是否已經(jīng)過期,如果沒過期則返回用戶,如果過期則刪除。

    但是這兩個(gè)策略都無法保證過期key一定刪除,漏網(wǎng)之魚越來越多,還可能導(dǎo)致內(nèi)存溢出。當(dāng)發(fā)生內(nèi)存不足問題時(shí),Redis還會(huì)做內(nèi)存回收。內(nèi)存回收采用LRU策略,就是最近最少使用。其原理就是記錄每個(gè)Key的最近使用時(shí)間,內(nèi)存回收時(shí),隨機(jī)抽取一些Key,比較其使用時(shí)間,把最老的幾個(gè)刪除。

    Redis的邏輯是:最近使用過的,很可能再次被使用

    3.7.Redis在項(xiàng)目中的哪些地方有用到?

    (1)共享session

    在分布式系統(tǒng)下,服務(wù)會(huì)部署在不同的tomcat,因此多個(gè)tomcat的session無法共享,以前存儲(chǔ)在session中的數(shù)據(jù)無法實(shí)現(xiàn)共享,可以用redis代替session,解決分布式系統(tǒng)間數(shù)據(jù)共享問題。

    (2)數(shù)據(jù)緩存

    Redis采用內(nèi)存存儲(chǔ),讀寫效率較高。我們可以把數(shù)據(jù)庫(kù)的訪問頻率高的熱點(diǎn)數(shù)據(jù)存儲(chǔ)到redis中,這樣用戶請(qǐng)求時(shí)優(yōu)先從redis中讀取,減少數(shù)據(jù)庫(kù)壓力,提高并發(fā)能力。

    (3)異步隊(duì)列

    Reids在內(nèi)存存儲(chǔ)引擎領(lǐng)域的一大優(yōu)點(diǎn)是提供 list 和 set 操作,這使得Redis能作為一個(gè)很好的消息隊(duì)列平臺(tái)來使用。而且Redis中還有pub/sub這樣的專用結(jié)構(gòu),用于1對(duì)N的消息通信模式。

    (4)分布式鎖

    Redis中的樂觀鎖機(jī)制,可以幫助我們實(shí)現(xiàn)分布式鎖的效果,用于解決分布式系統(tǒng)下的多線程安全問題

    3.8.Redis的緩存擊穿、緩存雪崩、緩存穿透

    1)緩存穿透

    參考資料:

    • 什么是緩存穿透

      • 正常情況下,我們?nèi)ゲ樵償?shù)據(jù)都是存在。那么請(qǐng)求去查詢一條壓根兒數(shù)據(jù)庫(kù)中根本就不存在的數(shù)據(jù),也就是緩存和數(shù)據(jù)庫(kù)都查詢不到這條數(shù)據(jù),但是請(qǐng)求每次都會(huì)打到數(shù)據(jù)庫(kù)上面去。這種查詢不存在數(shù)據(jù)的現(xiàn)象我們稱為緩存穿透

    • 穿透帶來的問題

      • 試想一下,如果有黑客會(huì)對(duì)你的系統(tǒng)進(jìn)行攻擊,拿一個(gè)不存在的id 去查詢數(shù)據(jù),會(huì)產(chǎn)生大量的請(qǐng)求到數(shù)據(jù)庫(kù)去查詢。可能會(huì)導(dǎo)致你的數(shù)據(jù)庫(kù)由于壓力過大而宕掉。

    • 解決辦法

      • 緩存空值:之所以會(huì)發(fā)生穿透,就是因?yàn)榫彺嬷袥]有存儲(chǔ)這些空數(shù)據(jù)的key。從而導(dǎo)致每次查詢都到數(shù)據(jù)庫(kù)去了。那么我們就可以為這些key對(duì)應(yīng)的值設(shè)置為null 丟到緩存里面去。后面再出現(xiàn)查詢這個(gè)key 的請(qǐng)求的時(shí)候,直接返回null 。這樣,就不用在到數(shù)據(jù)庫(kù)中去走一圈了,但是別忘了設(shè)置過期時(shí)間。

      • BloomFilter(布隆過濾):將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的bitmap中,一個(gè)一定不存在的數(shù)據(jù)會(huì)被 這個(gè)bitmap攔截掉,從而避免了對(duì)底層存儲(chǔ)系統(tǒng)的查詢壓力。在緩存之前在加一層 BloomFilter ,在查詢的時(shí)候先去 BloomFilter 去查詢 key 是否存在,如果不存在就直接返回,存在再走查緩存 -> 查 DB。

    話術(shù):

    緩存穿透有兩種解決方案:其一是把不存在的key設(shè)置null值到緩存中。其二是使用布隆過濾器,在查詢緩存前先通過布隆過濾器判斷key是否存在,存在再去查詢緩存。

    設(shè)置null值可能被惡意針對(duì),攻擊者使用大量不存在的不重復(fù)key ,那么方案一就會(huì)緩存大量不存在key數(shù)據(jù)。此時(shí)我們還可以對(duì)Key規(guī)定格式模板,然后對(duì)不存在的key做正則規(guī)范匹配,如果完全不符合就不用存null值到redis,而是直接返回錯(cuò)誤。

    2)緩存擊穿

    相關(guān)資料

    • 什么是緩存擊穿?

    key可能會(huì)在某些時(shí)間點(diǎn)被超高并發(fā)地訪問,是一種非常“熱點(diǎn)”的數(shù)據(jù)。這個(gè)時(shí)候,需要考慮一個(gè)問題:緩存被“擊穿”的問題。

    當(dāng)這個(gè)key在失效的瞬間,redis查詢失敗,持續(xù)的大并發(fā)就穿破緩存,直接請(qǐng)求數(shù)據(jù)庫(kù),就像在一個(gè)屏障上鑿開了一個(gè)洞。

    • 解決方案:

      • 使用互斥鎖(mutex key):mutex,就是互斥。簡(jiǎn)單地來說,就是在緩存失效的時(shí)候(判斷拿出來的值為空),不是立即去load db,而是先使用Redis的SETNX去set一個(gè)互斥key,當(dāng)操作返回成功時(shí),再進(jìn)行l(wèi)oad db的操作并回設(shè)緩存;否則,就重試整個(gè)get緩存的方法。SETNX,是「SET if Not eXists」的縮寫,也就是只有不存在的時(shí)候才設(shè)置,可以利用它來實(shí)現(xiàn)互斥的效果。

      • 軟過期:也就是邏輯過期,不使用redis提供的過期時(shí)間,而是業(yè)務(wù)層在數(shù)據(jù)中存儲(chǔ)過期時(shí)間信息。查詢時(shí)由業(yè)務(wù)程序判斷是否過期,如果數(shù)據(jù)即將過期時(shí),將緩存的時(shí)效延長(zhǎng),程序可以派遣一個(gè)線程去數(shù)據(jù)庫(kù)中獲取最新的數(shù)據(jù),其他線程這時(shí)看到延長(zhǎng)了的過期時(shí)間,就會(huì)繼續(xù)使用舊數(shù)據(jù),等派遣的線程獲取最新數(shù)據(jù)后再更新緩存。

    推薦使用互斥鎖,因?yàn)檐涍^期會(huì)有業(yè)務(wù)邏輯侵入和額外的判斷。

    面試話術(shù)

    緩存擊穿主要擔(dān)心的是某個(gè)Key過期,更新緩存時(shí)引起對(duì)數(shù)據(jù)庫(kù)的突發(fā)高并發(fā)訪問。因此我們可以在更新緩存時(shí)采用互斥鎖控制,只允許一個(gè)線程去更新緩存,其它線程等待并重新讀取緩存。例如Redis的setnx命令就能實(shí)現(xiàn)互斥效果。

    3)緩存雪崩

    相關(guān)資料

    緩存雪崩,是指在某一個(gè)時(shí)間段,緩存集中過期失效。對(duì)這批數(shù)據(jù)的訪問查詢,都落到了數(shù)據(jù)庫(kù)上,對(duì)于數(shù)據(jù)庫(kù)而言,就會(huì)產(chǎn)生周期性的壓力波峰。

    解決方案:

    • 數(shù)據(jù)分類分批處理:采取不同分類數(shù)據(jù),緩存不同周期

    • 相同分類數(shù)據(jù):采用固定時(shí)長(zhǎng)加隨機(jī)數(shù)方式設(shè)置緩存

    • 熱點(diǎn)數(shù)據(jù)緩存時(shí)間長(zhǎng)一些,冷門數(shù)據(jù)緩存時(shí)間短一些

    • 避免redis節(jié)點(diǎn)宕機(jī)引起雪崩,搭建主從集群,保證高可用

    面試話術(shù):

    解決緩存雪崩問題的關(guān)鍵是讓緩存Key的過期時(shí)間分散。因此我們可以把數(shù)據(jù)按照業(yè)務(wù)分類,然后設(shè)置不同過期時(shí)間。相同業(yè)務(wù)類型的key,設(shè)置固定時(shí)長(zhǎng)加隨機(jī)數(shù)。盡可能保證每個(gè)Key的過期時(shí)間都不相同。

    另外,Redis宕機(jī)也可能導(dǎo)致緩存雪崩,因此我們還要搭建Redis主從集群及哨兵監(jiān)控,保證Redis的高可用。

    3.9.緩存冷熱數(shù)據(jù)分離

    背景資料

    Redis使用的是內(nèi)存存儲(chǔ),當(dāng)需要海量數(shù)據(jù)存儲(chǔ)時(shí),成本非常高。

    經(jīng)過調(diào)研發(fā)現(xiàn),當(dāng)前主流DDR3內(nèi)存和主流SATA SSD的單位成本價(jià)格差距大概在20倍左右,為了優(yōu)化redis機(jī)器綜合成本,我們考慮實(shí)現(xiàn)基于熱度統(tǒng)計(jì) 的數(shù)據(jù)分級(jí)存儲(chǔ)及數(shù)據(jù)在RAM/FLASH之間的動(dòng)態(tài)交換,從而大幅度降低成本,達(dá)到性能與成本的高平衡。

    基本思路:基于key訪問次數(shù)(LFU)的熱度統(tǒng)計(jì)算法識(shí)別出熱點(diǎn)數(shù)據(jù),并將熱點(diǎn)數(shù)據(jù)保留在redis中,對(duì)于無訪問/訪問次數(shù)少的數(shù)據(jù)則轉(zhuǎn)存到SSD上,如果SSD上的key再次變熱,則重新將其加載到redis內(nèi)存中。

    目前流行的高性能磁盤存儲(chǔ),并且遵循Redis協(xié)議的方案包括:

    • SSDB:SSDB - 高性能的支持豐富數(shù)據(jù)結(jié)構(gòu)的 NoSQL 數(shù)據(jù)庫(kù), 替代 Redis

    • RocksDB:RocksDB中文網(wǎng) | 一個(gè)持久型的key-value存儲(chǔ)

    因此,我們就需要在應(yīng)用程序與緩存服務(wù)之間引入代理,實(shí)現(xiàn)Redis和SSD之間的切換,如圖:

    ?

    3.10.Redis實(shí)現(xiàn)分布式鎖

    分布式鎖要滿足的條件:

    • 多進(jìn)程互斥:同一時(shí)刻,只有一個(gè)進(jìn)程可以獲取鎖

    • 保證鎖可以釋放:任務(wù)結(jié)束或出現(xiàn)異常,鎖一定要釋放,避免死鎖

    • 阻塞鎖(可選):獲取鎖失敗時(shí)可否重試

    • 重入鎖(可選):獲取鎖的代碼遞歸調(diào)用時(shí),依然可以獲取鎖

    1)最基本的分布式鎖:

    利用Redis的setnx命令,這個(gè)命令的特征時(shí)如果多次執(zhí)行,只有第一次執(zhí)行會(huì)成功,可以實(shí)現(xiàn)互斥的效果。但是為了保證服務(wù)宕機(jī)時(shí)也可以釋放鎖,需要利用expire命令給鎖設(shè)置一個(gè)有效期

    setnx lock thread-01 # 嘗試獲取鎖 expire lock 10 # 設(shè)置有效期

    面試官問題1:如果expire之前服務(wù)宕機(jī)怎么辦?

    要保證setnx和expire命令的原子性。redis的set命令可以滿足:

    set key value [NX] [EX time]

    需要添加nx和ex的選項(xiàng):

    • NX:與setnx一致,第一次執(zhí)行成功

    • EX:設(shè)置過期時(shí)間

    面試官問題2:釋放鎖的時(shí)候,如果自己的鎖已經(jīng)過期了,此時(shí)會(huì)出現(xiàn)安全漏洞,如何解決?

    在鎖中存儲(chǔ)當(dāng)前進(jìn)程和線程標(biāo)識(shí),釋放鎖時(shí)對(duì)鎖的標(biāo)識(shí)判斷,如果是自己的則刪除,不是則放棄操作。

    但是這兩步操作要保證原子性,需要通過Lua腳本來實(shí)現(xiàn)。

    if redis.call("get",KEYS[1]) == ARGV[1] thenredis.call("del",KEYS[1]) end

    2)可重入分布式鎖

    如果有重入的需求,則除了在鎖中記錄進(jìn)程標(biāo)識(shí),還要記錄重試次數(shù),流程如下:

    ?

    下面我們假設(shè)鎖的key為“l(fā)ock”,hashKey是當(dāng)前線程的id:“threadId”,鎖自動(dòng)釋放時(shí)間假設(shè)為20

    獲取鎖的步驟:

    • 1、判斷l(xiāng)ock是否存在 EXISTS lock

      • 存在,說明有人獲取鎖了,下面判斷是不是自己的鎖

        • 判斷當(dāng)前線程id作為hashKey是否存在:HEXISTS lock threadId

          • 不存在,說明鎖已經(jīng)有了,且不是自己獲取的,鎖獲取失敗,end

          • 存在,說明是自己獲取的鎖,重入次數(shù)+1:HINCRBY lock threadId 1,去到步驟3

      • 2、不存在,說明可以獲取鎖,HSET key threadId 1

      • 3、設(shè)置鎖自動(dòng)釋放時(shí)間,EXPIRE lock 20

    釋放鎖的步驟:

    • 1、判斷當(dāng)前線程id作為hashKey是否存在:HEXISTS lock threadId

      • 不存在,說明鎖已經(jīng)失效,不用管了

      • 存在,說明鎖還在,重入次數(shù)減1:HINCRBY lock threadId -1,獲取新的重入次數(shù)

    • 2、判斷重入次數(shù)是否為0:

      • 為0,說明鎖全部釋放,刪除key:DEL lock

      • 大于0,說明鎖還在使用,重置有效時(shí)間:EXPIRE lock 20

    對(duì)應(yīng)的Lua腳本如下:

    首先是獲取鎖:

    local key = KEYS[1]; -- 鎖的key local threadId = ARGV[1]; -- 線程唯一標(biāo)識(shí) local releaseTime = ARGV[2]; -- 鎖的自動(dòng)釋放時(shí)間if(redis.call('exists', key) == 0) then -- 判斷是否存在redis.call('hset', key, threadId, '1'); -- 不存在, 獲取鎖redis.call('expire', key, releaseTime); -- 設(shè)置有效期return 1; -- 返回結(jié)果 end;if(redis.call('hexists', key, threadId) == 1) then -- 鎖已經(jīng)存在,判斷threadId是否是自己 redis.call('hincrby', key, threadId, '1'); -- 不存在, 獲取鎖,重入次數(shù)+1redis.call('expire', key, releaseTime); -- 設(shè)置有效期return 1; -- 返回結(jié)果 end; return 0; -- 代碼走到這里,說明獲取鎖的不是自己,獲取鎖失敗

    然后是釋放鎖:

    local key = KEYS[1]; -- 鎖的key local threadId = ARGV[1]; -- 線程唯一標(biāo)識(shí) local releaseTime = ARGV[2]; -- 鎖的自動(dòng)釋放時(shí)間if (redis.call('HEXISTS', key, threadId) == 0) then -- 判斷當(dāng)前鎖是否還是被自己持有return nil; -- 如果已經(jīng)不是自己,則直接返回 end; local count = redis.call('HINCRBY', key, threadId, -1); -- 是自己的鎖,則重入次數(shù)-1if (count > 0) then -- 判斷是否重入次數(shù)是否已經(jīng)為0redis.call('EXPIRE', key, releaseTime); -- 大于0說明不能釋放鎖,重置有效期然后返回return nil; elseredis.call('DEL', key); -- 等于0說明可以釋放鎖,直接刪除return nil; end;

    3)高可用的鎖

    面試官問題:redis分布式鎖依賴與redis,如果redis宕機(jī)則鎖失效。如何解決?

    此時(shí)大多數(shù)同學(xué)會(huì)回答說:搭建主從集群,做數(shù)據(jù)備份。

    這樣就進(jìn)入了陷阱,因?yàn)槊嬖嚬俚南乱粋€(gè)問題就來了:

    面試官問題:如果搭建主從集群做數(shù)據(jù)備份時(shí),進(jìn)程A獲取鎖,master還沒有把數(shù)據(jù)備份到slave,master宕機(jī),slave升級(jí)為master,此時(shí)原來鎖失效,其它進(jìn)程也可以獲取鎖,出現(xiàn)安全問題。如何解決?

    關(guān)于這個(gè)問題,Redis官網(wǎng)給出了解決方案,使用RedLock思路可以解決:

    在Redis的分布式環(huán)境中,我們假設(shè)有N個(gè)Redis master。這些節(jié)點(diǎn)完全互相獨(dú)立,不存在主從復(fù)制或者其他集群協(xié)調(diào)機(jī)制。之前我們已經(jīng)描述了在Redis單實(shí)例下怎么安全地獲取和釋放鎖。我們確保將在每(N)個(gè)實(shí)例上使用此方法獲取和釋放鎖。在這個(gè)樣例中,我們假設(shè)有5個(gè)Redis master節(jié)點(diǎn),這是一個(gè)比較合理的設(shè)置,所以我們需要在5臺(tái)機(jī)器上面或者5臺(tái)虛擬機(jī)上面運(yùn)行這些實(shí)例,這樣保證他們不會(huì)同時(shí)都宕掉。

    為了取到鎖,客戶端應(yīng)該執(zhí)行以下操作:

  • 獲取當(dāng)前Unix時(shí)間,以毫秒為單位。

  • 依次嘗試從N個(gè)實(shí)例,使用相同的key和隨機(jī)值獲取鎖。在步驟2,當(dāng)向Redis設(shè)置鎖時(shí),客戶端應(yīng)該設(shè)置一個(gè)網(wǎng)絡(luò)連接和響應(yīng)超時(shí)時(shí)間,這個(gè)超時(shí)時(shí)間應(yīng)該小于鎖的失效時(shí)間。例如你的鎖自動(dòng)失效時(shí)間為10秒,則超時(shí)時(shí)間應(yīng)該在5-50毫秒之間。這樣可以避免服務(wù)器端Redis已經(jīng)掛掉的情況下,客戶端還在死死地等待響應(yīng)結(jié)果。如果服務(wù)器端沒有在規(guī)定時(shí)間內(nèi)響應(yīng),客戶端應(yīng)該盡快嘗試另外一個(gè)Redis實(shí)例。

  • 客戶端使用當(dāng)前時(shí)間減去開始獲取鎖時(shí)間(步驟1記錄的時(shí)間)就得到獲取鎖使用的時(shí)間。當(dāng)且僅當(dāng)從大多數(shù)(這里是3個(gè)節(jié)點(diǎn))的Redis節(jié)點(diǎn)都取到鎖,并且使用的時(shí)間小于鎖失效時(shí)間時(shí),鎖才算獲取成功。

  • 如果取到了鎖,key的真正有效時(shí)間等于有效時(shí)間減去獲取鎖所使用的時(shí)間(步驟3計(jì)算的結(jié)果)。

  • 如果因?yàn)槟承┰?#xff0c;獲取鎖失敗(沒有在至少N/2+1個(gè)Redis實(shí)例取到鎖或者取鎖時(shí)間已經(jīng)超過了有效時(shí)間),客戶端應(yīng)該在所有的Redis實(shí)例上進(jìn)行解鎖(即便某些Redis實(shí)例根本就沒有加鎖成功)。

  • 3.11.如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)與緩存數(shù)據(jù)一致?

    面試話術(shù):

    實(shí)現(xiàn)方案有下面幾種:

    • 本地緩存同步:當(dāng)前微服務(wù)的數(shù)據(jù)庫(kù)數(shù)據(jù)與緩存數(shù)據(jù)同步,可以直接在數(shù)據(jù)庫(kù)修改時(shí)加入對(duì)Redis的修改邏輯,保證一致。

    • 跨服務(wù)緩存同步:服務(wù)A調(diào)用了服務(wù)B,并對(duì)查詢結(jié)果緩存。服務(wù)B數(shù)據(jù)庫(kù)修改,可以通過MQ通知服務(wù)A,服務(wù)A修改Redis緩存數(shù)據(jù)

    • 通用方案:使用Canal框架,偽裝成MySQL的salve節(jié)點(diǎn),監(jiān)聽MySQL的binLog變化,然后修改Redis緩存數(shù)據(jù)

    總結(jié)

    以上是生活随笔為你收集整理的b站黑马springCloud-常见面试题,多多三连的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    天天操天天干天天干 | 人人搞人人爽 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 婷婷在线视频 | 中字幕视频在线永久在线观看免费 | 亚洲欧美一区二区三区孕妇写真 | 伊人五月天.com | 日本久久片 | 久久艹人人 | 五月天最新网址 | 天天插天天干天天操 | 九月婷婷人人澡人人添人人爽 | 国产午夜影院 | 成人久久久久久久久 | av成人免费网站 | 开心激情五月婷婷 | 中文字幕二区在线观看 | 天天干干| 91av电影在线观看 | 国产精品 999 | 亚洲国产精品成人精品 | 人人爽人人看 | 午夜视频黄 | 日韩在线观看视频一区二区三区 | 91亚洲精品在线观看 | 992tv在线成人免费观看 | 麻豆国产在线播放 | 黄色三级在线观看 | 五月天久久久久 | 黄色在线观看免费网站 | 久久久亚洲影院 | 97在线公开视频 | 黄色大片网 | 国产v在线观看 | 在线视频国产区 | 激情综合电影网 | 在线观看久久 | 中文字幕一区二区三区在线视频 | 最新真实国产在线视频 | 国产免费成人 | 久爱精品在线 | 99久久久国产精品 | 亚洲视频一区二区三区在线观看 | 六月激情丁香 | 97色综合 | 丁香婷五月| 国产精品mv| 久草在线网址 | 国产一级片久久 | 一区二区三区高清在线 | 日本丰满少妇免费一区 | 美女网站黄在线观看 | 日本天天操| 麻花传媒mv免费观看 | 91视频在线免费看 | 97成人精品视频在线观看 | 亚洲国产欧美在线看片xxoo | 久久高清 | 黄色视屏免费在线观看 | 中文字幕在线看视频 | 日韩欧美一区二区三区免费观看 | 久久99精品久久久久久三级 | 亚洲综合在线发布 | 成年人免费观看国产 | 日韩一区二区三区高清在线观看 | 日韩精品免费在线视频 | 香蕉影视在线观看 | 91av在线看| 中文字幕在线高清 | 国产精品久久久久久久久久久不卡 | 粉嫩av一区二区三区四区 | 色a资源在线 | 久久久免费精品 | 久久久久久久久久久久亚洲 | 精品二区视频 | 国产精品女主播一区二区三区 | 久久成人精品视频 | 日韩三区在线观看 | 狠狠色狠狠综合久久 | 国产 欧美 日本 | 久久久久久毛片精品免费不卡 | 最新国产精品亚洲 | 精品国产视频在线观看 | 91久久国产露脸精品国产闺蜜 | 久久久香蕉视频 | 九九亚洲精品 | 久久亚洲福利视频 | 免费成人av | 日本黄网站 | 亚洲欧美日韩中文在线 | 色网免费观看 | 四虎免费在线观看视频 | 日韩丝袜 | 久久99国产一区二区三区 | 一区二区中文字幕在线播放 | 国产在线p | 色99在线 | 天天玩天天干天天操 | 99麻豆久久久国产精品免费 | 精品国产日本 | 国产日韩三级 | 中文字幕一区二区在线观看 | 五月婷婷在线观看 | 亚洲精品乱码久久久久久 | 2021久久 | 在线观看小视频 | 成年美女黄网站色大片免费看 | a级国产乱理论片在线观看 伊人宗合网 | 国产免费一区二区三区最新 | 日韩免费观看高清 | 欧美一级电影 | 91中文字幕在线观看 | 综合亚洲视频 | 欧美精品少妇xxxxx喷水 | 久久视频免费在线 | 91视频观看免费 | 成人免费观看电影 | 亚洲成a人片在线观看网站口工 | 亚洲精品 在线视频 | 五月天综合色 | 91视频麻豆 | 五月婷婷综合在线视频 | 精品91视频 | 999久久久精品视频 日韩高清www | 欧美日韩中 | 中文字幕在线网址 | 免费看黄在线观看 | 国产综合福利在线 | 中文字幕中文字幕在线中文字幕三区 | 久草在线看片 | 久久免费中文视频 | 亚洲高清在线精品 | 欧美日韩国产在线一区 | 免费成人av网站 | 中文一区二区三区在线观看 | 99av国产精品欲麻豆 | 在线观看你懂的网站 | 欧美日韩久久不卡 | 午夜性生活片 | 亚洲资源| 国产美女久久 | 亚洲爱av| 夜夜爽88888免费视频4848 | 日韩r级电影在线观看 | 爱爱av在线 | 看av免费网站 | 欧美 激情在线 | 人人天天夜夜 | 久久久国产精品网站 | 国产精品97| 国产成人精品久久久久蜜臀 | 黄色小说网站在线 | 国产精品久久久久久久久久直播 | 午夜精品99久久免费 | 日韩av免费大片 | 国产视频1区2区3区 久久夜视频 | 中文字幕最新精品 | 五月综合网站 | 国产精品24小时在线观看 | 亚洲一级免费电影 | 亚洲国内精品在线 | 福利视频一区二区 | 国产伦理一区二区 | 中日韩在线| 国产精品一区二区62 | 色婷婷激情四射 | 天天久久夜夜 | 久久人人爽人人爽人人片av软件 | 国产美女久久 | 婷婷六月天在线 | 狠狠干天天操 | 91黄色影视 | 欧美日韩中文字幕在线视频 | 91成人看片 | 国产美女无遮挡永久免费 | 黄色免费看片网站 | 亚洲天堂网视频在线观看 | 麻豆影视在线观看 | 日韩免费播放 | 在线国产一区 | 免费在线观看av | 亚洲精品一区二区三区在线观看 | 成人高清av在线 | 深爱激情综合网 | 男女免费av | 亚洲欧洲精品一区 | 久久高清毛片 | av成人黄色 | 久久国产精品一区二区三区 | 伊人久久电影网 | 波多野结衣亚洲一区二区 | 91在线中文| 成人免费在线观看入口 | 日韩高清三区 | 96国产在线 | 天天干天天操天天操 | 国产视频在线免费 | 国产一区二区三区免费视频 | 免费精品视频在线观看 | 国产精品视频大全 | 天天色天天射天天干 | 91看片麻豆 | 超碰97网站| 久久久在线免费观看 | 亚洲精品国偷拍自产在线观看蜜桃 | av在线播放亚洲 | 国产一区二区免费 | 国产精品综合久久久久久 | 在线视频久| 在线免费av网 | 久久伦理 | 摸bbb搡bbb搡bbbb | 中文字幕在线观看日本 | 久久精品国产免费观看 | 日韩黄色免费电影 | 成人av片免费观看app下载 | 国产剧情一区 | 日日干日日操 | 久久久久久久久久久久久久av | 中文字幕第一页在线视频 | 久久精品第一页 | 国产精品 久久 | 免费看一及片 | av免费网站 | av午夜电影| 国产精品久久久久永久免费看 | 亚洲国产资源 | 亚洲欧洲国产精品 | 91热爆视频 | 国产又粗又猛又色又黄网站 | 热久久国产 | 中文字幕在线视频一区二区 | 日韩专区在线观看 | 黄污视频网站 | 午夜视频在线观看一区二区三区 | 日本在线成人 | japanesefreesex中国少妇 | 97av色| 中文字幕日韩电影 | 日韩理论在线视频 | 91入口在线观看 | 欧美性生活大片 | 国产精品一区二区在线播放 | 日本99精品 | 国产在线观看二区 | 日日麻批40分钟视频免费观看 | 欧亚日韩精品一区二区在线 | www久久久久| 在线高清av | 国产免费作爱视频 | 中文在线亚洲 | 97超级碰碰碰碰久久久久 | 91在线资源| 久久免费看a级毛毛片 | 99在线视频精品 | 在线a人v观看视频 | 日日夜夜操操操操 | 国产精品久久久久久超碰 | 欧美色图亚洲图片 | 亚洲永久精品在线观看 | 97香蕉超级碰碰久久免费软件 | 五月婷婷六月丁香在线观看 | 三日本三级少妇三级99 | 亚洲电影免费 | 天天射天天射天天射 | 毛片网站在线观看 | 最新的av网站 | 操夜夜操 | 免费观看成人网 | 亚洲综合色激情五月 | 五月激情天 | 午夜精品一区二区三区可下载 | 天天爱天天色 | 成年人免费看的视频 | 精品91久久久久 | 99成人精品| 国产高清成人在线 | 在线观看黄网 | 在线观看国产亚洲 | 最近中文字幕久久 | 美女视频黄色免费 | 久久国产系列 | 国产午夜三级一区二区三桃花影视 | av电影中文 | 亚洲一区二区高潮无套美女 | 激情综合五月天 | 久久精品观看 | 园产精品久久久久久久7电影 | 欧美一级免费高清 | 黄色官网在线观看 | 午夜视频一区二区三区 | 视频二区在线 | 天天操操 | 欧美在线视频免费 | 丁香婷婷激情 | 国产精品手机看片 | www.天堂av | 日本性xxxxx 亚洲精品午夜久久久 | 视频一区二区国产 | 久久九九影视 | 中文字幕欧美日韩va免费视频 | 亚洲精品电影在线 | 免费91在线 | 日韩在线免费观看视频 | 亚洲伦理中文字幕 | 成人亚洲欧美 | 日日夜夜亚洲 | 波多野结衣一区三区 | 综合激情网... | 九九热1| 亚洲免费观看在线视频 | 久久精品99国产精品 | 伊人va | 在线精品亚洲 | 亚洲日本在线一区 | 精精国产xxxx视频在线播放 | 丁香激情五月 | 91久久在线观看 | 在线观看一级视频 | 色综合天天射 | 超碰97人 | 久久综合久久综合这里只有精品 | 欧美一区二区三区不卡 | 国产尤物在线 | 狠狠操狠狠干2017 | 亚洲涩涩涩涩涩涩 | 人人添人人澡 | 激情五月婷婷综合网 | 99热这里只有精品8 久久综合毛片 | 国产在线观看一区 | 热久在线| 天天天干天天天操 | 久艹在线免费观看 | 成人免费一级片 | 天天av综合网 | www99精品 | 91看国产 | 亚洲激精日韩激精欧美精品 | 亚洲欧洲视频 | 国产美女免费观看 | 亚洲一区日韩精品 | 色99视频 | 视频一区二区免费 | 免费高清看电视网站 | 在线观看视频一区二区三区 | 久久久亚洲国产精品麻豆综合天堂 | 中文在线免费视频 | 国产精品第三页 | 五月婷综合 | av免费在线网站 | 超碰精品在线观看 | 国产精品麻豆三级一区视频 | 一区二区三区在线观看免费视频 | 精品久久网站 | 国产精品成人免费一区久久羞羞 | 亚洲精品小视频 | 天天操狠狠操 | a天堂一码二码专区 | 亚洲欧洲精品久久 | 精久久久久| 精品国产aⅴ一区二区三区 在线直播av | 国产精品久久久久久影院 | 深夜福利视频一区二区 | 麻豆视频免费版 | av黄色一级片 | www.色午夜.com | 婷婷5月激情5月 | 日本少妇久久久 | 免费又黄又爽 | 欧美美女激情18p | 国产午夜精品理论片在线 | 国产精品综合在线观看 | 91丨九色丨勾搭 | 久久免费国产精品 | 国产v欧美 | 中文字幕永久 | 狠狠躁日日躁狂躁夜夜躁av | 婷婷九九| 日日干天天射 | 亚洲乱码在线观看 | 国产精品视频大全 | 精品久久网 | 久久香蕉国产精品麻豆粉嫩av | 日韩午夜视频在线观看 | 久久久久久久国产精品视频 | 久久视频免费在线 | 欧美另类xxx | www国产亚洲精品久久麻豆 | 亚洲精品伦理在线 | 国产午夜精品免费一区二区三区视频 | 亚洲少妇激情 | 国产一区电影在线观看 | 特级西西www44高清大胆图片 | 国产五十路毛片 | 深爱婷婷久久综合 | av免费片 | 麻豆视频免费版 | 精品中文字幕在线观看 | 日韩在线视频看看 | 五月色综合 | 国产精品白丝av | 欧美色操| 欧美日韩精品在线免费观看 | 国产99视频在线观看 | 日韩免费视频线观看 | 中文字幕色在线视频 | 亚洲经典在线 | 在线免费视频你懂的 | 爱爱一区 | 国产99久久久精品 | www91在线观看| 91久久精品一区 | 国产精品男女啪啪 | 久久精品成人热国产成 | 欧美日韩国产综合网 | 久久伊人八月婷婷综合激情 | 国产成人精品亚洲日本在线观看 | 欧美成年黄网站色视频 | 成人黄色电影在线观看 | 欧美最爽乱淫视频播放 | 久草在线电影网 | 久久精品网站视频 | 国产精品美女免费 | 狠狠狠色丁香婷婷综合久久五月 | 综合色综合 | 国产中文字幕三区 | 久久精品女人毛片国产 | 精品国产精品国产偷麻豆 | 视频一区在线播放 | 亚洲影院一区 | 韩国av在线播放 | 亚洲三级黄 | 色综合久久久久综合体桃花网 | 免费在线观看一级片 | 麻豆传媒视频在线免费观看 | 91成人在线看 | 99中文视频在线 | 日本久久久久久久久久 | 一区二区三区国 | 日韩久久精品一区二区三区 | 性色在线视频 | 免费成视频| 成人av在线直播 | 国产成人一级 | 中文成人字幕 | 国产伦精品一区二区三区在线 | 91视频 - x99av| 国产精品一区二区三区久久 | 日韩黄视频 | 国产精品不卡在线 | 麻豆国产露脸在线观看 | 日韩专区 在线 | 婷婷视频在线 | 成人在线你懂得 | 色综合久久综合 | 久久看片网 | 91免费高清 | 色诱亚洲精品久久久久久 | 日韩一三区 | 香蕉视频啪啪 | 日韩理论电影在线观看 | 免费高清影视 | 亚洲人成人在线 | 亚洲国产日韩av | 久久精品视频在线播放 | 亚洲伦理一区 | 天天射天天干天天 | 久久久99精品免费观看乱色 | 久久久久福利视频 | 韩国精品一区二区三区六区色诱 | 午夜精品av| 国产亚洲精品成人av久久影院 | 精产嫩模国品一二三区 | 99视频在线免费观看 | 超级碰碰视频 | 国产小视频免费观看 | 精品在线看 | 91成人午夜 | 久草在线免费播放 | 亚洲精品久久久久中文字幕m男 | 中文字幕一区二区三区四区在线视频 | 天天爽天天做 | 麻豆传媒视频在线 | 国产精品成人av电影 | 蜜臀久久99静品久久久久久 | 精品视频国产一区 | 玖草影院 | av免费播放 | free,性欧美 九九交易行官网 | 国产人成一区二区三区影院 | 少妇视频在线播放 | av色图天堂网 | 9999精品| 成人综合婷婷国产精品久久免费 | 国产精品自在线拍国产 | 99精品国产在热久久 | 黄色aaaaa| 成人毛片在线观看视频 | 久久人网 | 成人黄色小说在线观看 | 偷拍福利视频一区二区三区 | 日韩精品一区二区三区在线视频 | 亚洲黑丝少妇 | 国产96av | 色婷婷视频在线 | 日韩精品中文字幕有码 | 亚洲日本三级 | 久久er99热精品一区二区 | 在线观看日韩av | 97超碰人人澡人人爱学生 | 日本少妇高清做爰视频 | 欧美va天堂va视频va在线 | 999精品网 | 欧美精品久久久久久久久久白贞 | 一区二区三区免费在线观看视频 | 99精品热视频| 久久综合丁香 | 韩国在线一区 | 99草视频| 日日夜夜干| 国产亚洲精品美女久久 | 丝袜制服天堂 | 香蕉视频在线看 | 精品一二三四在线 | 97av.com| 欧美日韩视频在线一区 | 成人在线免费看视频 | 丁香九月激情综合 | 亚洲高清国产视频 | 久久成人18免费网站 | 免费视频二区 | 国产午夜精品一区二区三区 | 国产高清在线精品 | 在线视频精品播放 | 玖玖玖在线观看 | 欧美成人xxx| 亚洲国产成人在线 | 国产.精品.日韩.另类.中文.在线.播放 | 国产精品久久久久久久久久 | 国产午夜精品一区二区三区 | 97视频一区 | 精品欧美乱码久久久久久 | 日本三级全黄少妇三2023 | 一区 在线观看 | 免费欧美高清视频 | 久久精品牌麻豆国产大山 | 亚洲成人av电影 | 天天操天天拍 | 四虎国产精品成人免费影视 | 国产精品1区 | 国产精品99久久久精品免费观看 | 国产小视频在线观看免费 | 免费观看黄色12片一级视频 | 欧洲精品视频一区二区 | 国产视频日本 | 在线视频1卡二卡三卡 | 在线中文字幕av观看 | 高清视频一区 | av丝袜制服| 国产99久久久精品 | 国产无套精品久久久久久 | 久久国产网| 伊人婷婷网| 国产精品av电影 | 狠狠狠狠狠狠狠狠干 | 免费福利视频导航 | 亚州激情视频 | 粉嫩av一区二区三区四区在线观看 | 中文字幕欧美日韩va免费视频 | 很污的网站 | 免费中午字幕无吗 | 日韩视频一区二区三区在线播放免费观看 | 国产黄a三级三级三级三级三级 | 日韩精品在线观看av | 黄色影院在线观看 | 成人网444ppp| 久久av一区二区三区亚洲 | 国产福利一区二区三区在线观看 | 青青河边草免费视频 | 国产麻豆精品95视频 | 日本美女xx | 国产999精品久久久久久麻豆 | 中文字幕乱视频 | 中文字幕人成一区 | 久久久久久久电影 | 四虎影院在线观看av | 日韩黄色av网站 | 国产99精品在线观看 | 中文成人字幕 | 中文字幕精品一区久久久久 | 久久久国产精品一区二区三区 | 亚州精品视频 | 麻豆国产精品永久免费视频 | 成年人黄色大全 | 黄色在线免费观看网站 | 久久精品视频18 | 91专区在线观看 | 久久毛片网 | 人人狠狠综合久久亚洲婷 | 日韩精品视频在线观看免费 | 国产在线观看91 | 在线免费黄色片 | www日日 | 在线观看亚洲成人 | 国产精品99久久免费观看 | 在线观看午夜av | 日日躁夜夜躁xxxxaaaa | 97网在线观看 | 免费下载高清毛片 | 亚洲精品在线国产 | 午夜精品在线看 | 精品特级毛片 | 国产精品视频免费 | 婷婷色伊人| 黄网站色成年免费观看 | 操久在线| 国产精品久久久久久久久久直播 | 波多野结衣在线观看一区二区三区 | 久久久久久毛片精品免费不卡 | 黄色成品视频 | 99精品色 | 国产精品免费久久 | 亚洲va天堂va欧美ⅴa在线 | 精品一区在线看 | 国产欧美高清 | 国产一区福利 | 免费一级片在线 | 亚洲视频免费在线 | 久久黄色网址 | 丁香5月婷婷久久 | 在线国产福利 | 精品久久久久亚洲 | 日韩av专区| 极品美女被弄高潮视频网站 | 中文字幕刺激在线 | 欧美999| 日韩高清不卡一区二区三区 | 91精品国产高清 | 人人爽人人爽人人片av免 | 天天干夜夜操视频 | 蜜桃av久久久亚洲精品 | 91看片一区二区三区 | 97在线观看 | 在线免费观看羞羞视频 | 91香蕉视频色版 | 色综合久久五月天 | 这里只有精品视频在线 | 亚洲精品一区二区网址 | 免费观看一级特黄欧美大片 | 美女黄网久久 | 色婷婷国产 | 丁香花中文在线免费观看 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产系列在线观看 | 18国产精品福利片久久婷 | 97精品免费视频 | 九七视频在线观看 | 国产成人精品一区二区三区在线 | 免费黄色网止 | 91毛片在线 | 91人人澡人人爽人人精品 | 亚洲小视频在线 | 日日夜精品 | 手机在线永久免费观看av片 | 色偷偷中文字幕 | 亚洲人在线7777777精品 | 日女人电影 | 日本黄网站 | 成人av午夜| 欧美日本高清视频 | 在线免费观看国产 | 午夜精品久久久久久久99无限制 | 精品亚洲在线 | 亚洲视频电影在线 | 永久免费毛片在线观看 | 国产又粗又猛又色 | 亚洲国产丝袜在线观看 | 91成人久久| 欧美性生爱| 天天插天天爱 | 久久精品在线免费观看 | 国产精品视频免费 | 成年人毛片在线观看 | 日本久久成人 | 91久久国产精品 | 国产免费久久精品 | 91精品999 | 亚洲国产精久久久久久久 | 91精品推荐| 中文字幕一区二区三区久久 | 亚洲精品国偷拍自产在线观看 | 国产精品18p| 国产成人免费在线观看 | 日韩精品一区二区不卡 | 黄色三级视频片 | 国产日韩欧美视频 | 高清在线一区 | 免费黄色网止 | 国产福利中文字幕 | 91在线视频在线 | 日本公妇色中文字幕 | 亚洲精品在线一区二区 | 在线观看日本韩国电影 | 久久影院午夜论 | 成人宗合网 | 国产精品美女久久久久久网站 | 欧美国产高清 | 国产精品网在线观看 | 国产精品av一区二区 | 天天色.com| 国产欧美精品一区二区三区 | 欧美激情视频一区二区三区 | 日韩在线观看免费 | 性色xxxxhd | 国产成人精品亚洲 | 婷婷丁香色 | 天天干.com | 欧美一区二区三区免费观看 | 久久综合五月天婷婷伊人 | 51久久成人国产精品麻豆 | 天天综合网国产 | 日韩在线视频看看 | 在线有码中文字幕 | 狠狠插天天干 | 人人添人人澡人人澡人人人爽 | av免费黄色| 欧美日一级片 | 一级片免费观看视频 | 91精品久久久久久粉嫩 | 久草在线免费播放 | 国产高清视频网 | 久久无码精品一区二区三区 | 综合久久久久久久久 | 久久久精品一区二区 | 久久在草 | 97涩涩视频 | 午夜国产在线观看 | 婷婷久久婷婷 | 东方av免费在线观看 | 天天看天天干 | 欧美激情视频一区二区三区 | 91精品国自产在线 | 国产精品18久久久久久vr | 日韩羞羞 | 日韩午夜精品 | 国产999久久久 | 黄网站app在线观看免费视频 | 国产小视频免费在线网址 | 国产精品久久久久久久久毛片 | 天天操天天色综合 | 国产精品一区二区久久精品爱微奶 | 日本在线观看中文字幕 | 日日夜夜人人精品 | 97精产国品一二三产区在线 | 日韩中文字幕视频在线 | 深爱激情站 | 亚洲va在线va天堂 | 久久免费视频精品 | www日日夜夜| 色97在线| 激情视频免费在线观看 | 欧美国产日韩激情 | 西西人体4444www高清视频 | 午夜久久福利影院 | 国产不卡视频在线播放 | av在线播放国产 | 国产午夜不卡 | 97超碰免费 | 天堂在线视频中文网 | 久久成人亚洲欧美电影 | 亚洲资源在线观看 | 西西人体4444www高清视频 | 久久久www免费电影网 | 香蕉视频亚洲 | 欧美精品中文 | 日韩高清在线一区二区三区 | 激情综合交| 日本成址在线观看 | 91精品国产高清自在线观看 | 天天综合网在线观看 | 人人爱天天操 | av福利在线| 国产99免费| 国产精品久久久久久婷婷天堂 | 亚洲激情久久 | 国产精品一区免费在线观看 | 日韩欧美在线免费观看 | 激情五月播播久久久精品 | 久久久久久久亚洲精品 | 韩国精品福利一区二区三区 | 国产成人黄色av | 国产精品成人av在线 | 成年人视频在线观看免费 | 中文字幕一区二区三区视频 | 99综合久久 | 免费视频你懂得 | 日韩理论片 | 四虎影视欧美 | 国产高清在线不卡 | 亚洲视频在线免费观看 | 国产精品女同一区二区三区久久夜 | 992tv在线 | 深爱激情婷婷网 | 97麻豆视频| 深爱激情五月综合 | 人人操日日干 | 9999精品| 欧美性做爰猛烈叫床潮 | 狠狠的日日 | 国产精品久久久久免费 | 国产va饥渴难耐女保洁员在线观看 | 国产成人精品久久久久 | 黄色在线看网站 | 五月婷丁香 | 成人四虎影院 | 久久99精品久久久久久三级 | 免费午夜网站 | 国产一级免费在线 | 婷婷在线综合 | 亚洲黄色成人 | 啪啪午夜免费 | 免费手机黄色网址 | 成人av片免费观看app下载 | 亚洲精选视频在线 | 天天干天天操天天拍 | 国产精品久久艹 | 国产精品毛片一区视频播 | 久久久免费网站 | 精品久久久久久国产91 | www色,com| 91精品对白一区国产伦 | 国产精品无av码在线观看 | 五月婷婷在线观看视频 | 国产99在线播放 | av午夜电影 | 手机成人在线电影 | 日日干综合 | 尤物一区二区三区 | 成人国产在线 | 日韩免费视频在线观看 | 亚洲永久精品一区 | 亚洲日本va在线观看 | 17婷婷久久www | 99视频网站| 视频国产在线观看18 | 99久久久久久 | 99久久精品网 | 免费不卡中文字幕视频 | 在线观看中文字幕2021 | 在线观看国产高清视频 | 97在线观视频免费观看 | 欧美日本中文字幕 | 日本视频不卡 | 久爱精品在线 | www.久久精品视频 | 天天射天天拍 | 国产天天综合 | 久久免费高清视频 | 香蕉视频在线视频 | 天天操天天添 | 免费a网 | 中文字幕av免费在线观看 | 狠狠狠色狠狠色综合 | 国产精品久久久久久久99 | 91漂亮少妇露脸在线播放 | 亚洲aⅴ在线观看 | 亚洲日本欧美在线 | 99久久久国产精品 | 99九九视频 | 色婷婷综合久久久中文字幕 | 一区av在线播放 | 伊人丁香 | 欧美做受高潮1 | 国产一卡久久电影永久 | 怡春院av | 国产精品美女久久久久久久久 | 国产福利91精品一区二区三区 | 国产高清视频色在线www | 国产精品久久久久久久久久久久午夜片 | 91精品免费 | 亚洲精品国产精品国自产 | 97色免费视频| 五月婷婷在线综合 | 九九久久久久久久久激情 | 一区二区三区四区久久 | 91成人午夜| 日本超碰在线 | 中文字幕在线观看完整版电影 | 一本大道久久精品懂色aⅴ 五月婷社区 | 亚洲视频电影在线 | 一区二区欧美日韩 | 国产精品久久久久久久久久久久午 | 美女黄视频免费看 | 91香蕉国产在线观看软件 | 日韩在线精品一区 | 中文资源在线官网 | 亚洲精品www久久久 www国产精品com | 日日干夜夜骑 | av+在线播放在线播放 | 国产一区二区免费在线观看 | 国产精品久久久久久久久久直播 | 欧美一级免费黄色片 | 国产精品久久久久久久久免费看 | 最近2019好看的中文字幕免费 | 成人久久国产 | 国产成人av福利 | 一区二区三区在线观看免费视频 | 99热最新地址 | 涩涩伊人 | 九月婷婷人人澡人人添人人爽 | 久久er99热精品一区二区三区 | 在线观看韩日电影免费 | 黄污视频大全 | www.久久免费 | 特级西西444www高清大视频 | 99精品视频免费 | 在线免费av网站 | 日韩精品一区二区三区视频播放 | 天天超碰| 91在线中字 | 国产伦理一区二区三区 | 亚洲精品免费在线播放 | 五月婷综合 | 国内丰满少妇猛烈精品播 | 欧美性免费| 亚洲国产中文字幕在线视频综合 | 久久久久久久久久久久久9999 | 国产手机av在线 | 婷婷久久亚洲 | 91网在线观看 | 欧美另类亚洲 | 91精品久久久久久久91蜜桃 | 亚洲视频每日更新 | 久久av影视 | 欧美福利视频 | 成人av亚洲| 久草在线在线精品观看 | 91精品在线播放 | 国产精品99在线观看 | 黄色网在线免费观看 | 国产精品毛片久久久 | 中文字幕在线观看视频一区二区三区 | 色噜噜狠狠色综合中国 | 夜夜骑日日| 成人久久影院 | 四虎成人精品永久免费av九九 | 国产亚洲精品成人av久久影院 | 亚洲黄色在线免费观看 | 91麻豆精品国产自产在线 | 中文av网站| 一区二区三区精品久久久 | 五月天丁香亚洲 | 99久久精品视频免费 | 日韩一级片大全 | 91日本在线播放 | 在线视频 你懂得 | 色婷婷综合久久久久中文字幕1 | 999色视频| 伊人六月 | 丁香久久婷婷 | 免费一级片在线 | 国产污视频在线观看 | 99视频在线免费观看 | 一区二区三区动漫 | 免费成人av在线 | 热99在线| 久久国产精品一二三区 | 日韩精品视频久久 | 天堂av在线免费观看 | 久久久黄色 | 992tv成人免费看片 | 亚洲欧美国产精品18p | 国产日韩欧美在线影视 | 色综合久久66| 天天摸日日摸人人看 | 天天色天天上天天操 | 人人爽爽人人 | 国产一级片视频 | 国产美女搞久久 | 91视频久久久久久 | 毛片的网址 | 久久精品精品 | 日韩欧美精品在线 | 国产福利免费看 | 久久在线精品 | 久久精品国产亚洲精品2020 | 丝袜足交在线 | 久久1电影院 | 伊人六月| 久久国内精品99久久6app | 日本午夜免费福利视频 | 日韩在线观看高清 | 国产精品午夜免费福利视频 | 亚洲国产精品成人va在线观看 | 免费三级骚 | 久艹在线播放 | 一区二区三区免费看 | 天天天天天操 |