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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis 基础、高级特性与性能调优 | 高薪必备

發布時間:2025/3/21 数据库 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis 基础、高级特性与性能调优 | 高薪必备 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來源:http://c7.gg/fxqAK

本文將從Redis的基本特性入手,通過講述Redis的數據結構和主要命令對Redis的基本能力進行直觀介紹。之后概覽Redis提供的高級能力,并在部署、維護、性能調優等多個方面進行更深入的介紹和指導。

本文適合使用Redis的普通開發人員,以及對Redis進行選型、架構設計和性能調優的架構設計人員。

目錄

  • 概述

  • Redis的數據結構和相關常用命令

  • 數據持久化

  • 內存管理與數據淘汰機制

  • Pipelining

  • 事務與Scripting

  • Redis性能調優

  • 主從復制與集群分片

  • Redis Java客戶端的選擇

概述

Redis是一個開源的,基于內存的結構化數據存儲媒介,可以作為數據庫、緩存服務或消息服務使用。
Redis支持多種數據結構,包括字符串、哈希表、鏈表、集合、有序集合、位圖、Hyperloglogs等。
Redis具備LRU淘汰、事務實現、以及不同級別的硬盤持久化等能力,并且支持副本集和通過Redis Sentinel實現的高可用方案,同時還支持通過Redis Cluster實現的數據自動分片能力。

Redis的主要功能都基于單線程模型實現,也就是說Redis使用一個線程來服務所有的客戶端請求,同時Redis采用了非阻塞式IO,并精細地優化各種命令的算法時間復雜度,這些信息意味著:

  • Redis是線程安全的(因為只有一個線程),其所有操作都是原子的,不會因并發產生數據異常

  • Redis的速度非???#xff08;因為使用非阻塞式IO,且大部分命令的算法時間復雜度都是O(1))

  • 使用高耗時的Redis命令是很危險的,會占用唯一的一個線程的大量處理時間,導致所有的請求都被拖慢。(例如時間復雜度為O(N)的KEYS命令,嚴格禁止在生產環境中使用)

Redis的數據結構和相關常用命令

本節中將介紹Redis支持的主要數據結構,以及相關的常用Redis命令。本節只對Redis命令進行扼要的介紹,且只列出了較常用的命令。如果想要了解完整的Redis命令集,或了解某個命令的詳細使用方法,請參考官方文檔:

https://redis.io/commands

Key

Redis采用Key-Value型的基本數據結構,任何二進制序列都可以作為Redis的Key使用(例如普通的字符串或一張JPEG圖片)

關于Key的一些注意事項:

  • 不要使用過長的Key。例如使用一個1024字節的key就不是一個好主意,不僅會消耗更多的內存,還會導致查找的效率降低

  • Key短到缺失了可讀性也是不好的,例如”u1000flw”比起”user:1000:followers”來說,節省了寥寥的存儲空間,卻引發了可讀性和可維護性上的麻煩

  • 最好使用統一的規范來設計Key,比如”object-type:id:attr”,以這一規范設計出的Key可能是”user:1000″或”comment:1234:reply-to”

  • Redis允許的最大Key長度是512MB(對Value的長度限制也是512MB)

String

String是Redis的基礎數據類型,Redis沒有Int、Float、Boolean等數據類型的概念,所有的基本類型在Redis中都以String體現。

與String相關的常用命令:

  • SET:為一個key設置value,可以配合EX/PX參數指定key的有效期,通過NX/XX參數針對key是否存在的情況進行區別操作,時間復雜度O(1)

  • GET:獲取某個key對應的value,時間復雜度O(1)

  • GETSET:為一個key設置value,并返回該key的原value,時間復雜度O(1)

  • MSET:為多個key設置value,時間復雜度O(N)

  • MSETNX:同MSET,如果指定的key中有任意一個已存在,則不進行任何操作,時間復雜度O(N)

  • MGET:獲取多個key對應的value,時間復雜度O(N)

上文提到過,Redis的基本數據類型只有String,但Redis可以把String作為整型或浮點型數字來使用,主要體現在INCR、DECR類的命令上:

  • INCR:將key對應的value值自增1,并返回自增后的值。只對可以轉換為整型的String數據起作用。時間復雜度O(1)

  • INCRBY:將key對應的value值自增指定的整型數值,并返回自增后的值。只對可以轉換為整型的String數據起作用。時間復雜度O(1)

  • DECR/DECRBY:同INCR/INCRBY,自增改為自減。

INCR/DECR系列命令要求操作的value類型為String,并可以轉換為64位帶符號的整型數字,否則會返回錯誤。
也就是說,進行INCR/DECR系列命令的value,必須在[-2^63 ~ 2^63 – 1]范圍內。

前文提到過,Redis采用單線程模型,天然是線程安全的,這使得INCR/DECR命令可以非常便利的實現高并發場景下的精確控制。

例1:庫存控制

在高并發場景下實現庫存余量的精準校驗,確保不出現超賣的情況。

設置庫存總量:

SET?inv:remain?"100"

庫存扣減+余量校驗:

DECR?inv:remain

當DECR命令返回值大于等于0時,說明庫存余量校驗通過,如果返回小于0的值,則說明庫存已耗盡。

假設同時有300個并發請求進行庫存扣減,Redis能夠確保這300個請求分別得到99到-200的返回值,每個請求得到的返回值都是唯一的,絕對不會找出現兩個請求得到一樣的返回值的情況。

例2:自增序列生成

實現類似于RDBMS的Sequence功能,生成一系列唯一的序列號

設置序列起始值:

SET?sequence?"10000"

獲取一個序列值:

INCR?sequence

直接將返回值作為序列使用即可。

獲取一批(如100個)序列值:

INCRBY?sequence?100

假設返回值為N,那么[N – 99 ~ N]的數值都是可用的序列值。

當多個客戶端同時向Redis申請自增序列時,Redis能夠確保每個客戶端得到的序列值或序列范圍都是全局唯一的,絕對不會出現不同客戶端得到了重復的序列值的情況。

List

Redis的List是鏈表型的數據結構,可以使用LPUSH/RPUSH/LPOP/RPOP等命令在List的兩端執行插入元素和彈出元素的操作。雖然List也支持在特定index上插入和讀取元素的功能,但其時間復雜度較高(O(N)),應小心使用。

與List相關的常用命令:

  • LPUSH:向指定List的左側(即頭部)插入1個或多個元素,返回插入后的List長度。時間復雜度O(N),N為插入元素的數量

  • RPUSH:同LPUSH,向指定List的右側(即尾部)插入1或多個元素

  • LPOP:從指定List的左側(即頭部)移除一個元素并返回,時間復雜度O(1)

  • RPOP:同LPOP,從指定List的右側(即尾部)移除1個元素并返回

  • LPUSHX/RPUSHX:與LPUSH/RPUSH類似,區別在于,LPUSHX/RPUSHX操作的key如果不存在,則不會進行任何操作

  • LLEN:返回指定List的長度,時間復雜度O(1)

  • LRANGE:返回指定List中指定范圍的元素(雙端包含,即LRANGE key 0 10會返回11個元素),時間復雜度O(N)。應盡可能控制一次獲取的元素數量,一次獲取過大范圍的List元素會導致延遲,同時對長度不可預知的List,避免使用LRANGE key 0 -1這樣的完整遍歷操作。

應謹慎使用的List相關命令:

  • LINDEX:返回指定List指定index上的元素,如果index越界,返回nil。index數值是回環的,即-1代表List最后一個位置,-2代表List倒數第二個位置。時間復雜度O(N)

  • LSET:將指定List指定index上的元素設置為value,如果index越界則返回錯誤,時間復雜度O(N),如果操作的是頭/尾部的元素,則時間復雜度為O(1)

  • LINSERT:向指定List中指定元素之前/之后插入一個新元素,并返回操作后的List長度。如果指定的元素不存在,返回-1。如果指定key不存在,不會進行任何操作,時間復雜度O(N)

由于Redis的List是鏈表結構的,上述的三個命令的算法效率較低,需要對List進行遍歷,命令的耗時無法預估,在List長度大的情況下耗時會明顯增加,應謹慎使用。

換句話說,Redis的List實際是設計來用于實現隊列,而不是用于實現類似ArrayList這樣的列表的。如果你不是想要實現一個雙端出入的隊列,那么請盡量不要使用Redis的List數據結構。

為了更好支持隊列的特性,Redis還提供了一系列阻塞式的操作命令,如BLPOP/BRPOP等,能夠實現類似于BlockingQueue的能力,即在List為空時,阻塞該連接,直到List中有對象可以出隊時再返回。針對阻塞類的命令,此處不做詳細探討,請參考官方文檔(https://redis.io/topics/data-types-intro) 中”Blocking operations on lists”一節。

Hash

Hash即哈希表,Redis的Hash和傳統的哈希表一樣,是一種field-value型的數據結構,可以理解成將HashMap搬入Redis。

Hash非常適合用于表現對象類型的數據,用Hash中的field對應對象的field即可。

Hash的優點包括:

  • 可以實現二元查找,如”查找ID為1000的用戶的年齡”

  • 比起將整個對象序列化后作為String存儲的方法,Hash能夠有效地減少網絡傳輸的消耗

  • 當使用Hash維護一個集合時,提供了比List效率高得多的隨機訪問命令

與Hash相關的常用命令:

  • HSET:將key對應的Hash中的field設置為value。如果該Hash不存在,會自動創建一個。時間復雜度O(1)

  • HGET:返回指定Hash中field字段的值,時間復雜度O(1)

  • HMSET/HMGET:同HSET和HGET,可以批量操作同一個key下的多個field,時間復雜度:O(N),N為一次操作的field數量

  • HSETNX:同HSET,但如field已經存在,HSETNX不會進行任何操作,時間復雜度O(1)

  • HEXISTS:判斷指定Hash中field是否存在,存在返回1,不存在返回0,時間復雜度O(1)

  • HDEL:刪除指定Hash中的field(1個或多個),時間復雜度:O(N),N為操作的field數量

  • HINCRBY:同INCRBY命令,對指定Hash中的一個field進行INCRBY,時間復雜度O(1)

應謹慎使用的Hash相關命令:

  • HGETALL:返回指定Hash中所有的field-value對。返回結果為數組,數組中field和value交替出現。時間復雜度O(N)

  • HKEYS/HVALS:返回指定Hash中所有的field/value,時間復雜度O(N)

上述三個命令都會對Hash進行完整遍歷,Hash中的field數量與命令的耗時線性相關,對于尺寸不可預知的Hash,應嚴格避免使用上面三個命令,而改為使用HSCAN命令進行游標式的遍歷,具體請見?

https://redis.io/commands/scan

Set

Redis Set是無序的,不可重復的String集合。

與Set相關的常用命令:

  • SADD:向指定Set中添加1個或多個member,如果指定Set不存在,會自動創建一個。時間復雜度O(N),N為添加的member個數

  • SREM:從指定Set中移除1個或多個member,時間復雜度O(N),N為移除的member個數

  • SRANDMEMBER:從指定Set中隨機返回1個或多個member,時間復雜度O(N),N為返回的member個數

  • SPOP:從指定Set中隨機移除并返回count個member,時間復雜度O(N),N為移除的member個數

  • SCARD:返回指定Set中的member個數,時間復雜度O(1)

  • SISMEMBER:判斷指定的value是否存在于指定Set中,時間復雜度O(1)

  • SMOVE:將指定member從一個Set移至另一個Set

慎用的Set相關命令:

  • SMEMBERS:返回指定Hash中所有的member,時間復雜度O(N)

  • SUNION/SUNIONSTORE:計算多個Set的并集并返回/存儲至另一個Set中,時間復雜度O(N),N為參與計算的所有集合的總member數

  • SINTER/SINTERSTORE:計算多個Set的交集并返回/存儲至另一個Set中,時間復雜度O(N),N為參與計算的所有集合的總member數

  • SDIFF/SDIFFSTORE:計算1個Set與1或多個Set的差集并返回/存儲至另一個Set中,時間復雜度O(N),N為參與計算的所有集合的總member數

上述幾個命令涉及的計算量大,應謹慎使用,特別是在參與計算的Set尺寸不可知的情況下,應嚴格避免使用??梢钥紤]通過SSCAN命令遍歷獲取相關Set的全部member(具體請見?https://redis.io/commands/scan?),如果需要做并集/交集/差集計算,可以在客戶端進行,或在不服務實時查詢請求的Slave上進行。

Sorted Set

Redis Sorted Set是有序的、不可重復的String集合。Sorted Set中的每個元素都需要指派一個分數(score),Sorted Set會根據score對元素進行升序排序。如果多個member擁有相同的score,則以字典序進行升序排序。

Sorted Set非常適合用于實現排名。

Sorted Set的主要命令:

  • ZADD:向指定Sorted Set中添加1個或多個member,時間復雜度O(Mlog(N)),M為添加的member數量,N為Sorted Set中的member數量

  • ZREM:從指定Sorted Set中刪除1個或多個member,時間復雜度O(Mlog(N)),M為刪除的member數量,N為Sorted Set中的member數量

  • ZCOUNT:返回指定Sorted Set中指定score范圍內的member數量,時間復雜度:O(log(N))

  • ZCARD:返回指定Sorted Set中的member數量,時間復雜度O(1)

  • ZSCORE:返回指定Sorted Set中指定member的score,時間復雜度O(1)

  • ZRANK/ZREVRANK:返回指定member在Sorted Set中的排名,ZRANK返回按升序排序的排名,ZREVRANK則返回按降序排序的排名。時間復雜度O(log(N))

  • ZINCRBY:同INCRBY,對指定Sorted Set中的指定member的score進行自增,時間復雜度O(log(N))

慎用的Sorted Set相關命令:

  • ZRANGE/ZREVRANGE:返回指定Sorted Set中指定排名范圍內的所有member,ZRANGE為按score升序排序,ZREVRANGE為按score降序排序,時間復雜度O(log(N)+M),M為本次返回的member數

  • ZRANGEBYSCORE/ZREVRANGEBYSCORE:返回指定Sorted Set中指定score范圍內的所有member,返回結果以升序/降序排序,min和max可以指定為-inf和+inf,代表返回所有的member。時間復雜度O(log(N)+M)

  • ZREMRANGEBYRANK/ZREMRANGEBYSCORE:移除Sorted Set中指定排名范圍/指定score范圍內的所有member。時間復雜度O(log(N)+M)

上述幾個命令,應盡量避免傳遞[0 -1]或[-inf +inf]這樣的參數,來對Sorted Set做一次性的完整遍歷,特別是在Sorted Set的尺寸不可預知的情況下。可以通過ZSCAN命令來進行游標式的遍歷(具體請見?https://redis.io/commands/scan?),或通過LIMIT參數來限制返回member的數量(適用于ZRANGEBYSCORE和ZREVRANGEBYSCORE命令),以實現游標式的遍歷。

Bitmap和HyperLogLog

Redis的這兩種數據結構相較之前的并不常用,在本文中只做簡要介紹,如想要詳細了解這兩種數據結構與其相關的命令,請參考官方文檔

https://redis.io/topics/data-types-intro?中的相關章節

Bitmap在Redis中不是一種實際的數據類型,而是一種將String作為Bitmap使用的方法??梢岳斫鉃閷tring轉換為bit數組。使用Bitmap來存儲true/false類型的簡單數據極為節省空間。

HyperLogLogs是一種主要用于數量統計的數據結構,它和Set類似,維護一個不可重復的String集合,但是HyperLogLogs并不維護具體的member內容,只維護member的個數。也就是說,HyperLogLogs只能用于計算一個集合中不重復的元素數量,所以它比Set要節省很多內存空間。

其他常用命令

  • EXISTS:判斷指定的key是否存在,返回1代表存在,0代表不存在,時間復雜度O(1)

  • DEL:刪除指定的key及其對應的value,時間復雜度O(N),N為刪除的key數量

  • EXPIRE/PEXPIRE:為一個key設置有效期,單位為秒或毫秒,時間復雜度O(1)

  • TTL/PTTL:返回一個key剩余的有效時間,單位為秒或毫秒,時間復雜度O(1)

  • RENAME/RENAMENX:將key重命名為newkey。使用RENAME時,如果newkey已經存在,其值會被覆蓋;使用RENAMENX時,如果newkey已經存在,則不會進行任何操作,時間復雜度O(1)

  • TYPE:返回指定key的類型,string, list, set, zset, hash。時間復雜度O(1)

  • CONFIG GET:獲得Redis某配置項的當前值,可以使用*通配符,時間復雜度O(1)

  • CONFIG SET:為Redis某個配置項設置新值,時間復雜度O(1)

  • CONFIG REWRITE:讓Redis重新加載redis.conf中的配置

數據持久化

Redis提供了將數據定期自動持久化至硬盤的能力,包括RDB和AOF兩種方案,兩種方案分別有其長處和短板,可以配合起來同時運行,確保數據的穩定性。

必須使用數據持久化嗎?

Redis的數據持久化機制是可以關閉的。如果你只把Redis作為緩存服務使用,Redis中存儲的所有數據都不是該數據的主體而僅僅是同步過來的備份,那么可以關閉Redis的數據持久化機制。
但通常來說,仍然建議至少開啟RDB方式的數據持久化,因為:

  • RDB方式的持久化幾乎不損耗Redis本身的性能,在進行RDB持久化時,Redis主進程唯一需要做的事情就是fork出一個子進程,所有持久化工作都由子進程完成

  • Redis無論因為什么原因crash掉之后,重啟時能夠自動恢復到上一次RDB快照中記錄的數據。這省去了手工從其他數據源(如DB)同步數據的過程,而且要比其他任何的數據恢復方式都要快

  • 現在硬盤那么大,真的不缺那一點地方

RDB

采用RDB持久方式,Redis會定期保存數據快照至一個rbd文件中,并在啟動時自動加載rdb文件,恢復之前保存的數據。可以在配置文件中配置Redis進行快照保存的時機:

save?[seconds]?[changes]

意為在[seconds]秒內如果發生了[changes]次數據修改,則進行一次RDB快照保存,例如

save?60?100

會讓Redis每60秒檢查一次數據變更情況,如果發生了100次或以上的數據變更,則進行RDB快照保存。

可以配置多條save指令,讓Redis執行多級的快照保存策略。

Redis默認開啟RDB快照,默認的RDB策略如下:

save?900?1

save?300?10

save?60?10000

也可以通過BGSAVE命令手工觸發RDB快照保存。

RDB的優點:

  • 對性能影響最小。如前文所述,Redis在保存RDB快照時會fork出子進程進行,幾乎不影響Redis處理客戶端請求的效率。

  • 每次快照會生成一個完整的數據快照文件,所以可以輔以其他手段保存多個時間點的快照(例如把每天0點的快照備份至其他存儲媒介中),作為非常可靠的災難恢復手段。

  • 使用RDB文件進行數據恢復比使用AOF要快很多。

RDB的缺點:

  • 快照是定期生成的,所以在Redis crash時或多或少會丟失一部分數據。

  • 如果數據集非常大且CPU不夠強(比如單核CPU),Redis在fork子進程時可能會消耗相對較長的時間(長至1秒),影響這期間的客戶端請求。

AOF

采用AOF持久方式時,Redis會把每一個寫請求都記錄在一個日志文件里。在Redis重啟時,會把AOF文件中記錄的所有寫操作順序執行一遍,確保數據恢復到最新。

AOF默認是關閉的,如要開啟,進行如下配置:

appendonly?yes

AOF提供了三種fsync配置,always/everysec/no,通過配置項[appendfsync]指定:

  • appendfsync no:不進行fsync,將flush文件的時機交給OS決定,速度最快

  • appendfsync always:每寫入一條日志就進行一次fsync操作,數據安全性最高,但速度最慢

  • appendfsync everysec:折中的做法,交由后臺線程每秒fsync一次

隨著AOF不斷地記錄寫操作日志,必定會出現一些無用的日志,例如某個時間點執行了命令SET key1 “abc”,在之后某個時間點又執行了SET key1 “bcd”,那么第一條命令很顯然是沒有用的。大量的無用日志會讓AOF文件過大,也會讓數據恢復的時間過長。
所以Redis提供了AOF rewrite功能,可以重寫AOF文件,只保留能夠把數據恢復到最新狀態的最小寫操作集。

AOF rewrite可以通過BGREWRITEAOF命令觸發,也可以配置Redis定期自動進行:

auto-aof-rewrite-percentage?100

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

上面兩行配置的含義是,Redis在每次AOF rewrite時,會記錄完成rewrite后的AOF日志大小,當AOF日志大小在該基礎上增長了100%后,自動進行AOF rewrite。同時如果增長的大小沒有達到64mb,則不會進行rewrite。

AOF的優點:

  • 最安全,在啟用appendfsync always時,任何已寫入的數據都不會丟失,使用在啟用appendfsync everysec也至多只會丟失1秒的數據。

  • AOF文件在發生斷電等問題時也不會損壞,即使出現了某條日志只寫入了一半的情況,也可以使用redis-check-aof工具輕松修復。

  • AOF文件易讀,可修改,在進行了某些錯誤的數據清除操作后,只要AOF文件沒有rewrite,就可以把AOF文件備份出來,把錯誤的命令刪除,然后恢復數據。

AOF的缺點:

  • AOF文件通常比RDB文件更大

  • 性能消耗比RDB高

  • 數據恢復速度比RDB慢

內存管理與數據淘汰機制

最大內存設置

默認情況下,在32位OS中,Redis最大使用3GB的內存,在64位OS中則沒有限制。

在使用Redis時,應該對數據占用的最大空間有一個基本準確的預估,并為Redis設定最大使用的內存。否則在64位OS中Redis會無限制地占用內存(當物理內存被占滿后會使用swap空間),容易引發各種各樣的問題。

通過如下配置控制Redis使用的最大內存:

maxmemory?100mb

在內存占用達到了maxmemory后,再向Redis寫入數據時,Redis會:

  • 根據配置的數據淘汰策略嘗試淘汰數據,釋放空間

  • 如果沒有數據可以淘汰,或者沒有配置數據淘汰策略,那么Redis會對所有寫請求返回錯誤,但讀請求仍然可以正常執行

在為Redis設置maxmemory時,需要注意:

  • 如果采用了Redis的主從同步,主節點向從節點同步數據時,會占用掉一部分內存空間,如果maxmemory過于接近主機的可用內存,導致數據同步時內存不足。所以設置的maxmemory不要過于接近主機可用的內存,留出一部分預留用作主從同步。

數據淘汰機制

Redis提供了5種數據淘汰策略:

  • volatile-lru:使用LRU算法進行數據淘汰(淘汰上次使用時間最早的,且使用次數最少的key),只淘汰設定了有效期的key

  • allkeys-lru:使用LRU算法進行數據淘汰,所有的key都可以被淘汰

  • volatile-random:隨機淘汰數據,只淘汰設定了有效期的key

  • allkeys-random:隨機淘汰數據,所有的key都可以被淘汰

  • volatile-ttl:淘汰剩余有效期最短的key

最好為Redis指定一種有效的數據淘汰策略以配合maxmemory設置,避免在內存使用滿后發生寫入失敗的情況。

一般來說,推薦使用的策略是volatile-lru,并辨識Redis中保存的數據的重要性。對于那些重要的,絕對不能丟棄的數據(如配置類數據等),應不設置有效期,這樣Redis就永遠不會淘汰這些數據。對于那些相對不是那么重要的,并且能夠熱加載的數據(比如緩存最近登錄的用戶信息,當在Redis中找不到時,程序會去DB中讀取),可以設置上有效期,這樣在內存不夠時Redis就會淘汰這部分數據。

配置方法:

maxmemory-policy?volatile-lru???#默認是noeviction,即不進行數據淘汰

Pipelining

Pipelining

Redis提供許多批量操作的命令,如MSET/MGET/HMSET/HMGET等等,這些命令存在的意義是減少維護網絡連接和傳輸數據所消耗的資源和時間。

例如連續使用5次SET命令設置5個不同的key,比起使用一次MSET命令設置5個不同的key,效果是一樣的,但前者會消耗更多的RTT(Round Trip Time)時長,永遠應優先使用后者。

然而,如果客戶端要連續執行的多次操作無法通過Redis命令組合在一起,例如:

SET?a?"abc"

INCR?b

HSET?c?name?"hi"

此時便可以使用Redis提供的pipelining功能來實現在一次交互中執行多條命令。

使用pipelining時,只需要從客戶端一次向Redis發送多條命令(以rn)分隔,Redis就會依次執行這些命令,并且把每個命令的返回按順序組裝在一起一次返回,比如:

$?(printf?"PINGrnPINGrnPINGrn";?sleep?1)?|?nc?localhost?6379

+PONG

+PONG

+PONG

大部分的Redis客戶端都對Pipelining提供支持,所以開發者通常并不需要自己手工拼裝命令列表。

Pipelining的局限性

Pipelining只能用于執行連續且無相關性的命令,當某個命令的生成需要依賴于前一個命令的返回時,就無法使用Pipelining了。

通過Scripting功能,可以規避這一局限性

事務與Scripting

Pipelining能夠讓Redis在一次交互中處理多條命令,然而在一些場景下,我們可能需要在此基礎上確保這一組命令是連續執行的。

比如獲取當前累計的PV數并將其清0

>?GET?vCount

12384

>?SET?vCount?0

OK

如果在GET和SET命令之間插進來一個INCR vCount,就會使客戶端拿到的vCount不準確。

Redis的事務可以確保復數命令執行時的原子性。也就是說Redis能夠保證:一個事務中的一組命令是絕對連續執行的,在這些命令執行完成之前,絕對不會有來自于其他連接的其他命令插進去執行。

通過MULTI和EXEC命令來把這兩個命令加入一個事務中:

>?MULTI

OK

>?GET vCount

QUEUED

>?SET?vCount?0

QUEUED

>?EXEC

1)?12384

2)?OK

Redis在接收到MULTI命令后便會開啟一個事務,這之后的所有讀寫命令都會保存在隊列中但并不執行,直到接收到EXEC命令后,Redis會把隊列中的所有命令連續順序執行,并以數組形式返回每個命令的返回結果。

可以使用DISCARD命令放棄當前的事務,將保存的命令隊列清空。

需要注意的是,Redis事務不支持回滾:

如果一個事務中的命令出現了語法錯誤,大部分客戶端驅動會返回錯誤,2.6.5版本以上的Redis也會在執行EXEC時檢查隊列中的命令是否存在語法錯誤,如果存在,則會自動放棄事務并返回錯誤。

但如果一個事務中的命令有非語法類的錯誤(比如對String執行HSET操作),無論客戶端驅動還是Redis都無法在真正執行這條命令之前發現,所以事務中的所有命令仍然會被依次執行。在這種情況下,會出現一個事務中部分命令成功部分命令失敗的情況,然而與RDBMS不同,Redis不提供事務回滾的功能,所以只能通過其他方法進行數據的回滾。

通過事務實現CAS

Redis提供了WATCH命令與事務搭配使用,實現CAS樂觀鎖的機制。

假設要實現將某個商品的狀態改為已售:

if(exec(HGET?stock:1001?state)?==?"in stock")

????exec(HSET?stock:1001?state?"sold");

這一偽代碼執行時,無法確保并發安全性,有可能多個客戶端都獲取到了”in stock”的狀態,導致一個庫存被售賣多次。

使用WATCH命令和事務可以解決這一問題:

exec(WATCH?stock:1001);

if(exec(HGET?stock:1001?state)?==?"in stock")?{

????exec(MULTI);

????exec(HSET?stock:1001?state?"sold");

????exec(EXEC);

}

WATCH的機制是:在事務EXEC命令執行時,Redis會檢查被WATCH的key,只有被WATCH的key從WATCH起始時至今沒有發生過變更,EXEC才會被執行。如果WATCH的key在WATCH命令到EXEC命令之間發生過變化,則EXEC命令會返回失敗。

Scripting

通過EVAL與EVALSHA命令,可以讓Redis執行LUA腳本。這就類似于RDBMS的存儲過程一樣,可以把客戶端與Redis之間密集的讀/寫交互放在服務端進行,避免過多的數據交互,提升性能。

Scripting功能是作為事務功能的替代者誕生的,事務提供的所有能力Scripting都可以做到。Redis官方推薦使用LUA Script來代替事務,前者的效率和便利性都超過了事務。

關于Scripting的具體使用,本文不做詳細介紹,請參考官方文檔?

https://redis.io/commands/eval

Redis性能調優

盡管Redis是一個非常快速的內存數據存儲媒介,也并不代表Redis不會產生性能問題。
前文中提到過,Redis采用單線程模型,所有的命令都是由一個線程串行執行的,所以當某個命令執行耗時較長時,會拖慢其后的所有命令,這使得Redis對每個任務的執行效率更加敏感。

針對Redis的性能優化,主要從下面幾個層面入手:

  • 最初的也是最重要的,確保沒有讓Redis執行耗時長的命令

  • 使用pipelining將連續執行的命令組合執行

  • 操作系統的Transparent huge pages功能必須關閉:

echo?never?> /sys/kernel/mm/transparent_hugepage/enabled

  • 如果在虛擬機中運行Redis,可能天然就有虛擬機環境帶來的固有延遲??梢酝ㄟ^./redis-cli –intrinsic-latency 100命令查看固有延遲。同時如果對Redis的性能有較高要求的話,應盡可能在物理機上直接部署Redis。

  • 檢查數據持久化策略

  • 考慮引入讀寫分離機制

長耗時命令

Redis絕大多數讀寫命令的時間復雜度都在O(1)到O(N)之間,在文本和官方文檔中均對每個命令的時間復雜度有說明。

通常來說,O(1)的命令是安全的,O(N)命令在使用時需要注意,如果N的數量級不可預知,則應避免使用。例如對一個field數未知的Hash數據執行HGETALL/HKEYS/HVALS命令,通常來說這些命令執行的很快,但如果這個Hash中的field數量極多,耗時就會成倍增長。
又如使用SUNION對兩個Set執行Union操作,或使用SORT對List/Set執行排序操作等時,都應該嚴加注意。

避免在使用這些O(N)命令時發生問題主要有幾個辦法:

  • 不要把List當做列表使用,僅當做隊列來使用

  • 通過機制嚴格控制Hash、Set、Sorted Set的大小

  • 可能的話,將排序、并集、交集等操作放在客戶端執行

  • 絕對禁止使用KEYS命令

  • 避免一次性遍歷集合類型的所有成員,而應使用SCAN類的命令進行分批的,游標式的遍歷

Redis提供了SCAN命令,可以對Redis中存儲的所有key進行游標式的遍歷,避免使用KEYS命令帶來的性能問題。同時還有SSCAN/HSCAN/ZSCAN等命令,分別用于對Set/Hash/Sorted Set中的元素進行游標式遍歷。SCAN類命令的使用請參考官方文檔:

https://redis.io/commands/scan

Redis提供了Slow Log功能,可以自動記錄耗時較長的命令。相關的配置參數有兩個:

slowlog-log-slower-than?xxxms??#執行時間慢于xxx毫秒的命令計入Slow Log

slowlog-max-len?xxx??#Slow Log的長度,即最大紀錄多少條Slow Log

使用SLOWLOG GET [number]命令,可以輸出最近進入Slow Log的number條命令。
使用SLOWLOG RESET命令,可以重置Slow Log

網絡引發的延遲

  • 盡可能使用長連接或連接池,避免頻繁創建銷毀連接

  • 客戶端進行的批量數據操作,應使用Pipeline特性在一次交互中完成。具體請參照本文的Pipelining章節

數據持久化引發的延遲

Redis的數據持久化工作本身就會帶來延遲,需要根據數據的安全級別和性能要求制定合理的持久化策略:

  • AOF + fsync always的設置雖然能夠絕對確保數據安全,但每個操作都會觸發一次fsync,會對Redis的性能有比較明顯的影響

  • AOF + fsync every second是比較好的折中方案,每秒fsync一次

  • AOF + fsync never會提供AOF持久化方案下的最優性能

  • 使用RDB持久化通常會提供比使用AOF更高的性能,但需要注意RDB的策略配置

  • 每一次RDB快照和AOF Rewrite都需要Redis主進程進行fork操作。fork操作本身可能會產生較高的耗時,與CPU和Redis占用的內存大小有關。根據具體的情況合理配置RDB快照和AOF Rewrite時機,避免過于頻繁的fork帶來的延遲

Redis在fork子進程時需要將內存分頁表拷貝至子進程,以占用了24GB內存的Redis實例為例,共需要拷貝24GB / 4kB * 8 = 48MB的數據。在使用單Xeon 2.27Ghz的物理機上,這一fork操作耗時216ms。

可以通過INFO命令返回的latest_fork_usec字段查看上一次fork操作的耗時(微秒)

Swap引發的延遲

當Linux將Redis所用的內存分頁移至swap空間時,將會阻塞Redis進程,導致Redis出現不正常的延遲。Swap通常在物理內存不足或一些進程在進行大量I/O操作時發生,應盡可能避免上述兩種情況的出現。

/proc/<pid>/smaps文件中會保存進程的swap記錄,通過查看這個文件,能夠判斷Redis的延遲是否由Swap產生。如果這個文件中記錄了較大的Swap size,則說明延遲很有可能是Swap造成的。

數據淘汰引發的延遲

當同一秒內有大量key過期時,也會引發Redis的延遲。在使用時應盡量將key的失效時間錯開。

引入讀寫分離機制

Redis的主從復制能力可以實現一主多從的多節點架構,在這一架構下,主節點接收所有寫請求,并將數據同步給多個從節點。

在這一基礎上,我們可以讓從節點提供對實時性要求不高的讀請求服務,以減小主節點的壓力。
尤其是針對一些使用了長耗時命令的統計類任務,完全可以指定在一個或多個從節點上執行,避免這些長耗時命令影響其他請求的響應。

關于讀寫分離的具體說明,請參見后續章節

主從復制與集群分片

主從復制

Redis支持一主多從的主從復制架構。一個Master實例負責處理所有的寫請求,Master將寫操作同步至所有Slave。

借助Redis的主從復制,可以實現讀寫分離和高可用:

  • 實時性要求不是特別高的讀請求,可以在Slave上完成,提升效率。特別是一些周期性執行的統計任務,這些任務可能需要執行一些長耗時的Redis命令,可以專門規劃出1個或幾個Slave用于服務這些統計任務

  • 借助Redis Sentinel可以實現高可用,當Master crash后,Redis Sentinel能夠自動將一個Slave晉升為Master,繼續提供服務

啟用主從復制非常簡單,只需要配置多個Redis實例,在作為Slave的Redis實例中配置:

slaveof?192.168.1.1?6379??#指定Master的IP和端口

當Slave啟動后,會從Master進行一次冷啟動數據同步,由Master觸發BGSAVE生成RDB文件推送給Slave進行導入,導入完成后Master再將增量數據通過Redis Protocol同步給Slave。之后主從之間的數據便一直以Redis Protocol進行同步

使用Sentinel做自動failover

Redis的主從復制功能本身只是做數據同步,并不提供監控和自動failover能力,要通過主從復制功能來實現Redis的高可用,還需要引入一個組件:Redis Sentinel

Redis Sentinel是Redis官方開發的監控組件,可以監控Redis實例的狀態,通過Master節點自動發現Slave節點,并在監測到Master節點失效時選舉出一個新的Master,并向所有Redis實例推送新的主從配置。

Redis Sentinel需要至少部署3個實例才能形成選舉關系。

關鍵配置:

另外需要注意的是,Redis Sentinel實現的自動failover不是在同一個IP和端口上完成的,也就是說自動failover產生的新Master提供服務的IP和端口與之前的Master是不一樣的,所以要實現HA,還要求客戶端必須支持Sentinel,能夠與Sentinel交互獲得新Master的信息才行。

集群分片

為何要做集群分片:

  • Redis中存儲的數據量大,一臺主機的物理內存已經無法容納

  • Redis的寫請求并發量大,一個Redis實例以無法承載

當上述兩個問題出現時,就必須要對Redis進行分片了。
Redis的分片方案有很多種,例如很多Redis的客戶端都自行實現了分片功能,也有向Twemproxy這樣的以代理方式實現的Redis分片方案。然而首選的方案還應該是Redis官方在3.0版本中推出的Redis Cluster分片方案。

本文不會對Redis Cluster的具體安裝和部署細節進行介紹,重點介紹Redis Cluster帶來的好處與弊端。

Redis Cluster的能力

  • 能夠自動將數據分散在多個節點上

  • 當訪問的key不在當前分片上時,能夠自動將請求轉發至正確的分片

  • 當集群中部分節點失效時仍能提供服務

其中第三點是基于主從復制來實現的,Redis Cluster的每個數據分片都采用了主從復制的結構,原理和前文所述的主從復制完全一致,唯一的區別是省去了Redis Sentinel這一額外的組件,由Redis Cluster負責進行一個分片內部的節點監控和自動failover。

Redis Cluster分片原理

Redis Cluster中共有16384個hash slot,Redis會計算每個key的CRC16,將結果與16384取模,來決定該key存儲在哪一個hash slot中,同時需要指定Redis Cluster中每個數據分片負責的Slot數。Slot的分配在任何時間點都可以進行重新分配。

客戶端在對key進行讀寫操作時,可以連接Cluster中的任意一個分片,如果操作的key不在此分片負責的Slot范圍內,Redis Cluster會自動將請求重定向到正確的分片上。

hash tags

在基礎的分片原則上,Redis還支持hash tags功能,以hash tags要求的格式明明的key,將會確保進入同一個Slot中。例如:{uiv}user:1000和{uiv}user:1001擁有同樣的hash tag {uiv},會保存在同一個Slot中。

使用Redis Cluster時,pipelining、事務和LUA Script功能涉及的key必須在同一個數據分片上,否則將會返回錯誤。如要在Redis Cluster中使用上述功能,就必須通過hash tags來確保一個pipeline或一個事務中操作的所有key都位于同一個Slot中。

有一些客戶端(如Redisson)實現了集群化的pipelining操作,可以自動將一個pipeline里的命令按key所在的分片進行分組,分別發到不同的分片上執行。但是Redis不支持跨分片的事務,事務和LUA Script還是必須遵循所有key在一個分片上的規則要求。

主從復制 vs 集群分片

在設計軟件架構時,要如何在主從復制和集群分片兩種部署方案中取舍呢?

從各個方面看,Redis Cluster都是優于主從復制的方案

  • Redis Cluster能夠解決單節點上數據量過大的問題

  • Redis Cluster能夠解決單節點訪問壓力過大的問題

  • Redis Cluster包含了主從復制的能力

那是不是代表Redis Cluster永遠是優于主從復制的選擇呢?

并不是。

軟件架構永遠不是越復雜越好,復雜的架構在帶來顯著好處的同時,一定也會帶來相應的弊端。采用Redis Cluster的弊端包括:

  • 維護難度增加。在使用Redis Cluster時,需要維護的Redis實例數倍增,需要監控的主機數量也相應增加,數據備份/持久化的復雜度也會增加。同時在進行分片的增減操作時,還需要進行reshard操作,遠比主從模式下增加一個Slave的復雜度要高。

  • 客戶端資源消耗增加。當客戶端使用連接池時,需要為每一個數據分片維護一個連接池,客戶端同時需要保持的連接數成倍增多,加大了客戶端本身和操作系統資源的消耗。

  • 性能優化難度增加。你可能需要在多個分片上查看Slow Log和Swap日志才能定位性能問題。

  • 事務和LUA Script的使用成本增加。在Redis Cluster中使用事務和LUA Script特性有嚴格的限制條件,事務和Script中操作的key必須位于同一個分片上,這就使得在開發時必須對相應場景下涉及的key進行額外的規劃和規范要求。如果應用的場景中大量涉及事務和Script的使用,如何在保證這兩個功能的正常運作前提下把數據平均分到多個數據分片中就會成為難點。

所以說,在主從復制和集群分片兩個方案中做出選擇時,應該從應用軟件的功能特性、數據和訪問量級、未來發展規劃等方面綜合考慮,只在確實有必要引入數據分片時再使用Redis Cluster。
下面是一些建議:

  • 需要在Redis中存儲的數據有多大?未來2年內可能發展為多大?這些數據是否都需要長期保存?是否可以使用LRU算法進行非熱點數據的淘汰?綜合考慮前面幾個因素,評估出Redis需要使用的物理內存。

  • 用于部署Redis的主機物理內存有多大?有多少可以分配給Redis使用?對比(1)中的內存需求評估,是否足夠用?

  • Redis面臨的并發寫壓力會有多大?在不使用pipelining時,Redis的寫性能可以超過10萬次/秒(更多的benchmark可以參考?https://redis.io/topics/benchmarks?)

  • 在使用Redis時,是否會使用到pipelining和事務功能?使用的場景多不多?

  • 綜合上面幾點考慮,如果單臺主機的可用物理內存完全足以支撐對Redis的容量需求,且Redis面臨的并發寫壓力距離Benchmark值還尚有距離,建議采用主從復制的架構,可以省去很多不必要的麻煩。同時,如果應用中大量使用pipelining和事務,也建議盡可能選擇主從復制架構,可以減少設計和開發時的復雜度。

    Redis Java客戶端的選擇

    Redis的Java客戶端很多,官方推薦的有三種:Jedis、Redisson和lettuce。

    在這里對Jedis和Redisson進行對比介紹

    Jedis:

    • 輕量,簡潔,便于集成和改造

    • 支持連接池

    • 支持pipelining、事務、LUA Scripting、Redis Sentinel、Redis Cluster

    • 不支持讀寫分離,需要自己實現

    • 文檔差(真的很差,幾乎沒有……)

    Redisson:

    • 基于Netty實現,采用非阻塞IO,性能高

    • 支持異步請求

    • 支持連接池

    • 支持pipelining、LUA Scripting、Redis Sentinel、Redis Cluster

    • 不支持事務,官方建議以LUA Scripting代替事務

    • 支持在Redis Cluster架構下使用pipelining

    • 支持讀寫分離,支持讀負載均衡,在主從復制和Redis Cluster架構下都可以使用

    • 內建Tomcat Session Manager,為Tomcat 6/7/8提供了會話共享功能

    • 可以與Spring Session集成,實現基于Redis的會話共享

    • 文檔較豐富,有中文文檔

    對于Jedis和Redisson的選擇,同樣應遵循前述的原理,盡管Jedis比起Redisson有各種各樣的不足,但也應該在需要使用Redisson的高級特性時再選用Redisson,避免造成不必要的程序復雜度提升。

    總結

    以上是生活随笔為你收集整理的Redis 基础、高级特性与性能调优 | 高薪必备的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    国产高清久久久 | 欧美一进一出抽搐大尺度视频 | 色久综合 | 91精品入口| 丝袜护士aⅴ在线白丝护士 天天综合精品 | 国产精品区二区三区日本 | 久久草在线免费 | 在线观看日韩精品 | 区一区二区三区中文字幕 | 91精品国产综合久久久久久久 | 久久免费视频4 | 亚洲免费资源 | www.五月天婷婷 | 高清免费av在线 | 国产v亚洲v | 精品在线视频一区 | 日韩免费高清在线 | 欧美在线视频免费 | 操操色 | 五月婷婷欧美视频 | 久久久高清免费视频 | 911精品美国片911久久久 | 国内视频一区二区 | 精品999在线 | 国产精品18久久久久vr手机版特色 | 国产一区二区在线看 | 成人av亚洲 | 中文字幕乱码一区二区 | 日本激情视频中文字幕 | 国产免费又粗又猛又爽 | 婷婷色在线观看 | 黄色影院在线免费观看 | 一区二区国产精品 | 天天综合导航 | 亚洲激情网站免费观看 | 91精品国自产在线观看 | 亚洲黄色小说网 | 久 久久影院| 国产97在线观看 | 色在线国产 | 国产免费不卡 | 久久免费黄色网址 | 天天干夜夜爽 | 久久久18 | 在线视频国产区 | 亚洲免费成人av电影 | 一本大道久久精品懂色aⅴ 五月婷社区 | 激情久久久| 午夜色婷婷 | 国内精品久久久久久久 | 在线观看免费 | 五月天久久久久久 | 日本婷婷色 | 国产69精品久久久久久 | 国产成人精品女人久久久 | 亚洲精品乱码久久久久久蜜桃欧美 | 视频一区二区免费 | 久久久视屏| 中国一级特黄毛片大片久久 | 99这里只有精品99 | 狠狠躁日日躁狂躁夜夜躁 | 亚洲国产精品成人av | 亚洲免费一级 | 免费网站看v片在线a | 欧美小视频在线 | av高清免费 | 久久成人国产精品免费软件 | 成人国产电影在线观看 | 亚洲一本视频 | 国产一卡久久电影永久 | 天天鲁一鲁摸一摸爽一爽 | 国产精品一区二区62 | 日日草视频 | 久久99久久99精品免观看粉嫩 | 欧美成人手机版 | 91在线影视| 日韩大陆欧美高清视频区 | 日韩av中文字幕在线免费观看 | 91在线观看视频网站 | 日本在线成人 | 欧美性久久久 | 日本中文乱码卡一卡二新区 | 国产精品手机在线播放 | 午夜 在线 | 手机看片1042 | 天堂网中文在线 | 亚洲一级国产 | 激情久久婷婷 | 国产.精品.日韩.另类.中文.在线.播放 | 国产美女精品视频免费观看 | 国产成人三级一区二区在线观看一 | 狠狠躁18三区二区一区ai明星 | 成av在线 | 在线免费观看国产黄色 | 99热在线这里只有精品 | 日韩欧美一区二区三区免费观看 | 午夜视频在线观看一区二区 | 91精品第一页 | 精品亚洲成人 | 国产999精品久久久久久绿帽 | 成人小视频在线播放 | 99产精品成人啪免费网站 | 久久成人18免费网站 | 久久99九九99精品 | 国产美腿白丝袜足在线av | 激情综合六月 | 夜色资源站国产www在线视频 | 国产视频首页 | 国产色 在线 | 麻豆视频www | 天天色天天草天天射 | 又爽又黄在线观看 | 欧美精品小视频 | av先锋影音少妇 | 免费网站在线观看成人 | 日韩av图片 | 一区二区三区精品在线视频 | 亚洲视频网站在线观看 | 日韩免费av在线 | 国产精品黑丝在线观看 | 中文字幕乱视频 | 欧美日韩久久不卡 | 国产91九色视频 | 亚洲一区不卡视频 | 国产精品毛片 | 国产 在线观看 | 日本黄区免费视频观看 | 最近中文字幕大全中文字幕免费 | 在线观看免费一区 | 黄色一级大片在线免费看产 | 美女网站视频久久 | 992tv成人免费看片 | 免费精品视频 | 国产精品中文字幕在线观看 | 激情五月婷婷综合网 | 在线免费观看视频 | 美女免费视频一区二区 | 精品国产亚洲一区二区麻豆 | 久久久综合色 | 久久免费中文视频 | 女人18毛片a级毛片一区二区 | 久久久精品小视频 | 男女全黄一级一级高潮免费看 | 久久久香蕉视频 | 中文字幕在线国产精品 | 怡红院成人在线 | 国产在线视频一区二区三区 | 国产一及片 | 亚洲精品在线资源 | 超碰在线94 | 黄网站www | 国产精品美女久久久久久久久 | 波多野结衣精品视频 | 精品久久久成人 | 天天干.com | 午夜在线免费观看视频 | 久久区二区 | 国产日本在线播放 | 日韩视频中文 | 色网址99 | 成片人卡1卡2卡3手机免费看 | 色噜噜日韩精品一区二区三区视频 | 久久99久久99精品免观看粉嫩 | 国产精品中文字幕av | 玖玖999| 精品视频99| 免费av黄色| 91国内在线 | 欧美黑人xxxx猛性大交 | 久久免费毛片 | 天天射天天操天天色 | 青青河边草手机免费 | 国产精品美女999 | av超碰在线 | 黄色在线免费观看网址 | 亚洲精品午夜一区人人爽 | 欧美精品中文在线免费观看 | 韩国av免费观看 | 国产精品久久久久久久av电影 | 亚洲欧美日韩精品一区二区 | 久久欧美视频 | 日韩免费视频观看 | 亚洲成人影音 | 激情欧美日韩一区二区 | 日日操夜夜操狠狠操 | av大全在线看 | 91大神精品视频在线观看 | 国产精品成人免费精品自在线观看 | 国产又粗又猛又黄又爽 | 最近中文字幕大全 | 射射射av | 九九久久久久久久久激情 | 2019中文最近的2019中文在线 | 久久精品视频在线播放 | 亚洲精品久久在线 | 最近2019年日本中文免费字幕 | 久久狠狠一本精品综合网 | 欧美精品一区二区三区一线天视频 | 免费色视频网站 | 国产精品亚洲精品 | 亚洲美女久久 | 97看片 | 日本成人免费在线观看 | 韩国精品一区二区三区六区色诱 | 国产玖玖精品视频 | 很黄很黄的网站免费的 | 久久久www成人免费毛片 | 婷婷在线资源 | 久久在线观看 | 丁香婷婷综合五月 | 国产老妇av | 黄色小视频在线观看免费 | 伊人激情综合 | 香蕉免费| 337p日本欧洲亚洲大胆裸体艺术 | 国产精品网站一区二区三区 | 五月开心六月婷婷 | 国产亚洲成av片在线观看 | 三上悠亚一区二区在线观看 | 狠狠艹夜夜干 | 亚洲精品美女久久17c | 国产精品久久久久久久久久久久冷 | 欧美一区二视频在线免费观看 | 国产精品久久久久久影院 | 久久精品久久99 | 亚洲精品乱码久久久久久蜜桃动漫 | 国产一区二区不卡视频 | 99久久久久久久久 | 亚洲最新av在线网站 | 欧美日韩久久一区 | 97超碰人人澡人人 | 天天干视频在线 | 久久免费视频在线观看6 | 成人影视免费 | 色福利网 | 伊人六月| 久久综合中文色婷婷 | 玖玖在线看 | av综合av| 999精品视频 | 中文乱幕日产无线码1区 | 天天草视频 | www.eeuss影院av撸 | 91精品一区二区在线观看 | 99久久日韩精品免费热麻豆美女 | 久久综合中文字幕 | 黄网站免费久久 | 国产日韩精品在线 | 日韩一二三区不卡 | 奇米网8888| 久久久免费观看完整版 | 男女全黄一级一级高潮免费看 | 国产又粗又硬又长又爽的视频 | 在线观看中文字幕av | 色综合天天综合网国产成人网 | 色播激情五月 | 欧美极度另类 | 69欧美视频 | 欧美一二三专区 | www.天天草 | 久久综合天天 | 色射色 | 色播五月激情五月 | 日韩免费视频观看 | 国产免费av一区二区三区 | 中文字幕久久精品亚洲乱码 | 亚洲人人精品 | 狠狠色丁香久久婷婷综合五月 | 天天曰天天射 | 丁香六月婷 | 日韩av电影中文字幕在线观看 | 黄色成品视频 | 日韩高清在线不卡 | 亚洲最大激情中文字幕 | 亚洲国产日韩av | 97在线观视频免费观看 | 精品一区精品二区 | 香蕉影院在线 | 日韩大片在线免费观看 | 色婷婷婷| 日韩r级在线 | 久久黄色小说视频 | 欧美日韩久久不卡 | av综合 日韩 | 色中色综合 | 国产我不卡 | 色综合久久精品 | 久久与婷婷 | 91片网 | 国产精品一区二区久久国产 | 欧美少妇xxxxxx| 国产一级视频在线免费观看 | 亚洲国产精品成人女人久久 | 黄色毛片视频 | 成x99人av在线www| 色片网站在线观看 | 日韩xxxxxxxxx | 国产精品久久久久三级 | 国产中文字幕91 | 国产日韩在线一区 | 亚州日韩中文字幕 | 亚洲五月婷 | 亚洲精品资源在线 | 色999在线 | 欧美污污视频 | 在线视频 区 | 亚洲精品视频一二三 | www.97色.com | 啪啪午夜免费 | 久久免费国产精品 | 国产网红在线 | 热久久免费国产视频 | 久草免费在线视频观看 | av一本久道久久波多野结衣 | 伊人伊成久久人综合网小说 | 在线免费观看视频一区 | 激情丁香综合五月 | 伊人激情网 | 成人免费xxx在线观看 | 欧美孕交vivoestv另类 | 日本久久精 | 日本最新一区二区三区 | 亚洲国产一区av | 国产999精品视频 | 午夜体验区 | 五月天婷婷免费视频 | 国产亚洲欧美一区 | 久久天天综合网 | 狠狠色丁香久久婷婷综合_中 | 国产精品99久久免费观看 | 久久久久女人精品毛片九一 | 久99视频 | 国产 日韩 在线 亚洲 字幕 中文 | 国产精品久久久久久久7电影 | 国产精品久久久久国产a级 激情综合中文娱乐网 | 欧美一级在线观看视频 | 一本色道久久精品 | 免费观看一区二区 | 免费av片在线 | 欧美午夜视频在线 | 久久久精品在线观看 | 欧美一二三区在线播放 | 久草视频在线新免费 | 精品国产一区二区在线 | 国产精品 日韩精品 | 亚洲精品视 | 免费网站v | 在线a人v观看视频 | 国产精品久久一区二区三区不卡 | 在线va视频| 精品在线看 | 中文字幕第一页在线vr | 久久久久免费看 | 久久激情婷婷 | 九九日九九操 | 综合激情网... | 成年人看片 | 97精品在线 | 婷婷五情天综123 | 永久免费视频国产 | 欧洲一区精品 | 国产91丝袜在线播放动漫 | 一区中文字幕在线观看 | 成人av免费在线观看 | 亚洲 成人 欧美 | 欧美福利网站 | 毛片二区 | 91精品国产一区二区在线观看 | 亚洲国产精品va在线 | 国产不卡精品视频 | 视频1区2区 | 亚洲视频第一页 | 国产精品欧美日韩 | 亚洲做受高潮欧美裸体 | 成人黄大片视频在线观看 | 人人干天天射 | 玖玖精品视频 | 中文字幕韩在线第一页 | 91人人视频在线观看 | 中文字幕欧美日韩va免费视频 | 91精品视频免费看 | 黄色午夜网站 | 午夜久久久久久久久久久 | 韩日av在线 | 免费网站污| 国产小视频免费在线网址 | 日韩电影在线一区二区 | 在线韩国电影免费观影完整版 | 日日碰狠狠躁久久躁综合网 | 毛片网站在线观看 | 国产午夜精品一区二区三区欧美 | 精品亚洲男同gayvideo网站 | 91视频成人免费 | 免费h漫在线观看 | 久久久久久看片 | 亚洲aⅴ乱码精品成人区 | 91九色porn在线资源 | 夜夜夜夜夜夜操 | 91天堂影院 | 免费在线国产精品 | 国产又粗又硬又爽视频 | 国内久久精品视频 | 婷婷五月情 | 国产精彩在线视频 | 美女搞黄国产视频网站 | 久久精品这里精品 | 人人草人人草 | 国产精品国内免费一区二区三区 | 婷婷色av | 一区二区三区韩国免费中文网站 | 成人在线视频在线观看 | 中文字幕第 | 亚洲一区二区三区91 | 肉色欧美久久久久久久免费看 | av中文字幕亚洲 | 国产精品国产毛片 | 久久国产免费看 | 免费进去里的视频 | 婷婷视频导航 | 日本h视频在线观看 | 在线视频你懂 | 91一区二区三区在线观看 | 国产亚洲精品久久久久秋 | 美女av免费| 亚洲伊人色 | 亚洲闷骚少妇在线观看网站 | 91av视频在线播放 | 高清av不卡 | 特黄特色特刺激视频免费播放 | 亚洲精品国产视频 | 一级黄色片在线免费看 | 亚洲另类久久 | 成人91av| 18性欧美xxxⅹ性满足 | 国产美女被啪进深处喷白浆视频 | 国产精品久久影院 | 中文字幕在线免费看 | 少妇视频一区 | 中文字幕一区二区三区乱码在线 | 国产黄色片在线 | 国产视频不卡一区 | 久草视频在线免费 | 国产精品99久久久久久久久久久久 | 久久久久观看 | 亚洲欧洲精品一区二区 | 国产精品欧美久久 | 丁香视频 | 国产一区在线视频观看 | 午夜91视频 | 成人久久18免费网站图片 | 欧美激情视频一二三区 | 中文亚洲欧美日韩 | 在线精品视频免费播放 | 天天色天天干天天色 | 蜜臀av一区二区 | 久久夜夜夜 | 亚洲精品视频免费在线 | 久久久久亚洲精品国产 | 亚洲一级片在线看 | 最新av电影网站 | 日韩av中文字幕在线免费观看 | 国产高h视频 | 免费在线看成人av | 亚洲美女精品 | 国内视频一区二区 | 成人在线免费av | 丁香婷婷综合色啪 | 久久精品a| 亚洲激情一区二区三区 | 欧美日韩不卡一区二区三区 | 精品99久久久久久 | 亚洲一级片av | 国产精品va在线播放 | 国产精品嫩草在线 | 久久综合五月天婷婷伊人 | 精品国产诱惑 | 久久精品视频观看 | av不卡中文字幕 | 日韩试看| 日韩有码专区 | 日本久久久精品视频 | 草久久av | jizz欧美性9 国产一区高清在线观看 | 人人爽久久涩噜噜噜网站 | 亚州激情视频 | 国产一区网址 | 在线看成人片 | 国产伦理一区二区 | 日本中文字幕免费观看 | 久草在线免费在线观看 | 手机av网站 | 91精品久久久久久久久 | 色网站在线免费观看 | 在线看片日韩 | 91九色在线播放 | 国产 欧美 日本 | 日本深夜福利视频 | 色婷婷综合久久久中文字幕 | 日韩av中文在线 | 中文区中文字幕免费看 | 国产一区二区电影在线观看 | 成人国产精品久久久春色 | 午夜久久成人 | 婷婷久久久久 | 免费观看91| 国产aaa大片| 97国产大学生情侣白嫩酒店 | 日韩欧美视频在线 | 久久婷婷久久 | 美女免费黄视频网站 | 九九综合九九综合 | 国产分类视频 | 99自拍视频在线观看 | 国产二区视频在线 | 亚洲成人av电影在线 | 天天天综合 | 国产午夜精品福利视频 | av免费在线免费观看 | 97av在线视频免费播放 | 激情视频区 | 国产精品一二三 | 国产中文字幕一区二区三区 | 国产精品久久一区二区三区, | 久久天天躁夜夜躁狠狠躁2022 | 国产丝袜美腿在线 | 91香蕉视频污在线 | 草久在线观看 | 91亚洲国产成人 | 国产精品不卡在线 | 中文伊人 | 婷婷色资源 | 成年人app网址 | 国产99在线播放 | 波多野结衣在线视频一区 | 九草在线视频 | 日韩剧| 日韩在观看线 | 91最新地址永久入口 | 在线观看免费av片 | 黄色三级网站在线观看 | 亚洲欧洲成人 | 天天操天天曰 | 久久 在线 | 在线免费观看av网站 | 中文在线中文a | 国产主播大尺度精品福利免费 | 热热热热热色 | 欧美一区成人 | www.色婷婷| 五月天狠狠操 | 在线a亚洲视频播放在线观看 | 久草在线看片 | 日本爱爱免费 | 九草视频在线 | 在线电影a | 欧美精品乱码久久久久久 | 精品国产a | 日韩免费在线观看视频 | 日韩欧美视频在线 | 夜夜躁狠狠躁日日躁 | 亚洲免费在线播放视频 | 国产五月| 国产色女 | 国产精品一区在线观看 | 97在线观看视频 | 色狠狠综合天天综合综合 | 999视频精品| 色偷偷888欧美精品久久久 | 日韩精品一区二区三区丰满 | 成人免费视频网址 | 一区二区不卡高清 | 欧美另类人妖 | 日日日操操 | 亚洲激情校园春色 | 一区精品久久 | 日韩不卡高清视频 | 人人插人人射 | 日韩欧美99| 视频91| 成人av一区二区三区 | 亚洲专区欧美 | 亚洲欧美日韩在线一区二区 | av成人动漫在线观看 | 成人精品视频久久久久 | 欧美日一级片 | 欧美一级高清片 | 激情深爱.com | 日韩精品一区二区三区丰满 | 亚洲成a人片在线观看网站口工 | 日韩在线观看一区二区三区 | 国产日韩亚洲 | 国产精国产精品 | 国产视频首页 | 四虎在线观看精品视频 | 国产香蕉在线 | 最新色站| 国产一区在线免费观看 | 在线观看视频国产一区 | 久久久免费精品国产一区二区 | 国产黄色视| 麻豆 videos| 成人免费观看视频大全 | 久久久久在线观看 | www.99热精品 | 国产精品第十页 | 亚洲精品乱码久久久久 | 婷婷天天色 | 国产资源精品在线观看 | 中文字幕在线免费 | 久久99精品久久久久久秒播蜜臀 | 国产成人高清在线 | 精品欧美一区二区精品久久 | 久久无码精品一区二区三区 | 丁香影院在线 | 麻豆免费观看视频 | 中文字幕一区在线 | 精品国产综合区久久久久久 | 久艹在线观看视频 | 亚洲欧美视频一区二区三区 | 日日夜夜天天人人 | 午夜婷婷在线播放 | 日本三级全黄少妇三2023 | 在线中文视频 | 精品国产一区二区三区日日嗨 | 在线欧美中文字幕 | 成人免费观看视频大全 | 国产一二区视频 | 欧美日韩亚洲第一页 | 亚洲精品一区二区三区新线路 | 9在线观看免费高清完整 | 日韩欧美99 | 98超碰在线观看 | 久久久精品久久 | 国产精品乱码久久久久久1区2区 | 色天天| 91亚洲精品乱码久久久久久蜜桃 | 日韩av午夜在线观看 | 狠狠操导航 | 国产视频一区在线免费观看 | 亚洲国产精彩中文乱码av | 91高清在线 | 色狠狠狠 | 久久不射电影网 | 国产大陆亚洲精品国产 | 久久草av| 中文字幕免费播放 | 在线看日韩 | 深爱激情五月婷婷 | 美女网站久久 | 日韩丝袜 | 欧美日韩中文字幕综合视频 | 成年人免费电影在线观看 | 亚洲精选久久 | 免费的黄色av| 国产精品99久久久久的智能播放 | 97在线播放| 伊人夜夜 | 亚洲人成人在线 | 久久久久国产精品免费 | 国产高清视频 | 国产日韩在线一区 | 精品国产乱码一区二 | 国产黑丝一区二区三区 | 日韩黄色免费电影 | 国产成人久久av977小说 | 青青草在久久免费久久免费 | 91日韩在线播放 | 中文字幕精品在线 | 天天插天天爽 | 久久精品第一页 | 中文在线8新资源库 | 日韩久久久久久久久 | 亚洲美女免费精品视频在线观看 | 六月久久婷婷 | 免费在线成人av电影 | 免费看污网站 | 香蕉影视在线观看 | 日韩激情片在线观看 | 天天操夜夜操天天射 | 亚洲精品久久久久999中文字幕 | 国产91在线免费视频 | 奇米影视777四色米奇影院 | 国产人成精品一区二区三 | 99亚洲国产精品 | 国产无限资源在线观看 | 92国产精品久久久久首页 | 日韩色中色 | 久久精品国产免费观看 | 日日躁你夜夜躁你av蜜 | 国产精品麻豆99久久久久久 | 色婷婷成人网 | 久久久久麻豆v国产 | 成人在线免费看 | 色婷婷激婷婷情综天天 | 精品视频不卡 | 日韩成人免费电影 | 一本之道乱码区 | 欧美性生交大片免网 | 友田真希av| 日韩av电影中文字幕在线观看 | 丁香花在线视频观看免费 | 久草久草久草久草 | 欧美精品亚洲精品日韩精品 | 国产麻豆精品久久 | 91精品国产99久久久久久红楼 | 亚洲在线视频免费 | 国产精品久久久久久久久久久久午夜片 | 久久精品一区二区三区国产主播 | 丁香婷婷激情网 | 少妇搡bbbb搡bbb搡aa | 欧美疯狂性受xxxxx另类 | 最近日本中文字幕a | 色狠狠一区二区 | 久久黄视频 | 在线蜜桃视频 | 狠狠色免费 | 日韩亚洲精品电影 | 亚洲国产精品成人女人久久 | 精品影院 | 欧美日韩综合在线 | 中文字幕 第二区 | 久久精品99国产精品酒店日本 | 欧美激情精品久久 | 天天摸日日摸人人看 | 日韩啪啪小视频 | 中文字幕一区二区三区四区久久 | 五月激情站 | 国产亚洲午夜高清国产拍精品 | 中文字幕在线观看第一区 | 日本久久免费视频 | 在线观看免费视频你懂的 | 99视频一区 | 美女视频久久久 | 在线免费观看国产 | 97久久久免费福利网址 | 免费观看国产视频 | 日韩成人精品一区二区 | 最新一区二区三区 | 午夜久操| 精品xxx| 日韩高清二区 | www.久久婷婷 | 日韩在线精品一区 | 国产精品二区在线 | 99视频精品在线 | 精品久久中文 | 狠狠操影视 | 99色在线播放 | 蜜臀久久99精品久久久无需会员 | 男女日麻批 | 日韩资源视频 | 婷婷视频导航 | 五月丁香 | 又长又大又黑又粗欧美 | 国产精品美女久久 | 能在线看的av | 伊人伊成久久人综合网站 | 伊人黄 | 免费精品国产va自在自线 | 天天色天天色天天色 | 中文字幕色在线 | www.久久色| 97视频在线观看成人 | 怡红院av| 久久精品欧美一区二区三区麻豆 | 国产做a爱一级久久 | 黄色网址在线播放 | 在线国产精品视频 | 日韩久久精品一区二区三区下载 | 97超碰在线久草超碰在线观看 | 久久99国产精品久久99 | 日韩中文字幕在线观看 | 亚洲国产精品视频 | 亚洲免费在线播放视频 | 中文字幕 在线 一 二 | 久久国产精品第一页 | 日本bbbb摸bbbb | 久久免费黄色网址 | 最新日韩视频 | 麻豆久久精品 | 在线观看黄网站 | 97看片吧| 国产色在线 | 天堂网一区二区 | 国产高清av在线播放 | 7777精品伊人久久久大香线蕉 | 久久99亚洲网美利坚合众国 | 在线视频欧美日韩 | 国产又粗又猛又黄 | 日韩欧美69 | 黄色官网在线观看 | 日日操天天射 | 91丨精品丨蝌蚪丨白丝jk | 国产69精品久久久久99尤 | 久久午夜影视 | 亚洲五月激情 | 国产无遮挡又黄又爽馒头漫画 | 日韩高清免费电影 | 日日草av | 西西大胆啪啪 | 五月婷婷中文字幕 | 成人av高清| 国产亚州精品视频 | 手机成人免费视频 | 亚洲欧美视频在线观看 | 国产精久久久久久妇女av | 91chinesexxx| 日韩色在线观看 | 欧美一级久久久久 | 亚洲精品在线观看中文字幕 | 久久夜色精品国产欧美乱极品 | 91在线看黄 | 久久久免费在线观看 | 国产一区在线视频 | 精品久久一区二区三区 | 国产视频97| 天天草天天操 | 亚州精品一二三区 | 大胆欧美gogo免费视频一二区 | 成人av片免费看 | 99热这里只有精品在线观看 | 国产成人精品一区二区在线观看 | 制服丝袜亚洲 | 亚洲黄色免费网站 | 国产精品久久久999 国产91九色视频 | 人人爽人人爽人人爽学生一级 | 又色又爽的网站 | 日日爱网站| 久久成电影| 综合伊人久久 | 久久只有精品 | 午夜电影一区 | 男女激情网址 | 亚洲国产日韩欧美在线 | 色资源中文字幕 | 日日干日日色 | 婷婷综合视频 | 久久成人一区二区 | 免费看久久 | 久久成人精品视频 | 午夜国产一区二区 | 超碰人人舔 | 婷婷国产在线观看 | 一级大片在线观看 | 免费在线观看av | 国产精品网红直播 | 日韩精品你懂的 | 91在线中字 | 在线观看深夜视频 | 插插插色综合 | 91网址在线观看 | 黄色影院在线免费观看 | 久久99久久99免费视频 | 91精彩视频在线观看 | 国产综合视频在线观看 | 久久在线免费视频 | av激情五月 | 国产成人一区二区精品非洲 | 九九热视频在线播放 | 日韩丝袜在线观看 | 国产资源精品在线观看 | 久久只精品99品免费久23小说 | 激情开心站 | 五月激情站 | 久久久午夜精品福利内容 | 国产精品久久亚洲 | 国产精品久久久久久久久久久久午 | 天天人人 | 国内精品久久久久久久影视简单 | 日日干天天干 | 九九综合九九综合 | 色婷婷国产精品一区在线观看 | 天天拍天天爽 | 999在线视频 | 九九在线播放 | 日本女人逼 | 天天看天天干 | 九九热免费在线视频 | 狠狠狠狠狠狠狠干 | 97精品超碰一区二区三区 | 精品视频一区在线观看 | 在线观看黄网站 | 国产 日韩 中文字幕 | 久久成人欧美 | 中文字幕在线一二 | 久久久私人影院 | 久久久久久久免费观看 | 免费观看一级视频 | 9ⅰ精品久久久久久久久中文字幕 | 国产福利91精品一区 | 亚洲三级视频 | 久久国产精品99精国产 | 日韩欧美一区二区三区在线观看 | 一区在线免费观看 | 免费黄在线看 | 中文字幕免费一区二区 | 久久怡红院 | 国产精品美女毛片真酒店 | 伊人婷婷| 99视频精品| 91热在线 | 欧美日韩一区二区三区视频 | 日韩一级电影网站 | 国产日韩精品在线观看 | 一级理论片在线观看 | 四虎影视成人永久免费观看亚洲欧美 | 四虎国产精品永久在线国在线 | 综合网天天| 日韩在线网 | 99精品国产99久久久久久97 | 四虎在线免费观看 | 欧美极品久久 | 日韩日韩日韩日韩 | 成人黄在线 | 四季av综合网站 | 国产精品久久久久久久久久新婚 | 在线视频免费观看 | 日韩区视频 | 日韩一区二区久久 | 国产精品成人一区二区 | 视频在线观看入口黄最新永久免费国产 | 欧美乱淫视频 | 久久99操 | 99久久精品国产欧美主题曲 | 久久久久亚洲精品中文字幕 | 久久狠狠一本精品综合网 | 成人av动漫在线 | 日韩精品播放 | 国产一级视频在线 | 毛片网站在线观看 | 91毛片视频 | 日韩特级黄色片 | 亚洲欧美视频一区二区三区 | 国产精品av免费在线观看 | 欧美一区二区精美视频 | 97成人超碰 | 国产精品色在线 | 中字幕视频在线永久在线观看免费 | 99久久久成人国产精品 | 国产精品原创av片国产免费 | 六月激情婷婷 | 国产偷v国产偷∨精品视频 在线草 | 久久免费大片 | 国产中的精品av小宝探花 | 人人干人人超 | 国产精品一区在线观看你懂的 | 69xxxx欧美| 日本丶国产丶欧美色综合 | 最新国产精品拍自在线播放 | 奇米先锋| 丁香激情视频 | 久影院 | 国产精美视频 | 九九九电影免费看 | 日韩视频中文字幕在线观看 | 色综合久久天天 | 精品一区二区三区在线播放 | 婷婷六月在线 | 国产在线视频一区 | 国产麻豆传媒 | 欧美色图p| 国产一级二级三级在线观看 | 二区视频在线观看 | 91成品人影院 | 天天干夜夜 | 五月天激情在线 | 91传媒免费在线观看 | 中文字幕有码在线观看 | 成人午夜精品久久久久久久3d | 亚洲激情在线视频 | 91热视频 | 亚洲日韩欧美一区二区在线 | 欧美日韩三级在线观看 | 免费日韩 精品中文字幕视频在线 | 成 人 黄 色 视频播放1 | 精品国产乱码久久久久久久 | 久久综合日| av黄色免费在线观看 | 国产成人精品一区二区三区福利 | 狠狠操操| 色一级片| 国产精品国产毛片 | 精品视频在线视频 | 在线网址你懂得 | 久草在线最新视频 | 亚洲视频,欧洲视频 | 欧美日韩一区二区视频在线观看 | 激情网站网址 | 午夜精品一区二区三区免费视频 | 亚洲影院天堂 | 欧美激情精品久久久久久变态 | 亚洲国产精品成人综合 | 久久国产手机看片 | 精品一区二区三区久久 | 国产视频1 | av在线最新 | 亚洲欧美激情插 | 丁香五月亚洲综合在线 |