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

Redis 布隆過濾器實戰「緩存擊穿、雪崩效應」

存儲 存儲軟件 Redis
我們的業務中經常會遇到穿庫的問題,通常可以通過緩存解決。 如果數據維度比較多,結果數據集合比較大時,緩存的效果就不明顯了。

為什么引入

我們的業務中經常會遇到穿庫的問題,通常可以通過緩存解決。 如果數據維度比較多,結果數據集合比較大時,緩存的效果就不明顯了。 因此為了解決穿庫的問題,我們引入Bloom Filter。

我們先看看一般業務緩存流程:

 

先查詢緩存,緩存找不到再查詢數據庫。 然后將查詢結果放在緩存中即使數據不存在,也需要創建一個緩存,用來防止穿庫。這里需要區分一下數據是否存在。 如果數據不存在,緩存時間可以設置相對較短,防止因為主從同步等問題,導致問題被放大。

這個流程中存在薄弱的問題是,當用戶量太大時,我們會緩存大量數據空數據,并且一旦來一波冷用戶,會造成雪崩效應。 對于這種情況,我們產生第二個版本流程:redis過濾冷用戶緩存流程

 

我們將數據庫里面中選中的用戶放在redis的set類型中,設置不過期。 這樣相當把redis當作數據庫的索引,只要查詢redis,就可以知道是否數據存在。 redis中不存在就可以直接返回結果。 如果存在就按照上面提到一般業務緩存流程處理。

聰明的你肯定會想到更多的問題:

  1. redis本身可以做緩存,為什么不直接返回數據呢?
  2. 如果數據量比較大,單個set,會有性能問題?
  3. 業務不重要,將全量數據放在redis中,占用服務器大量內存。投入產出不成比例?

問題1需要區分業務場景,結果數據少,我們是可以直接使用redis作為緩存,直接返回數據。 結果比較大就不太適合用redis存放了。比如ugc內容,一個評論里面可能存在上萬字,業務字段多。

redis使用有很多技巧。bigkey 危害比較大,無論是擴容或縮容帶來的內存申請釋放, 還是查詢命令使用不當導致大量數據返回,都會影響redis的穩定。這里就不細談原因及危害了。 解決bigkey 方法很簡單。我們可以使用hash函數來分桶,將數據分散到多個key中。 減少單個key的大小,同時不影響查詢效率。

問題3是redis存儲占用內存太大。因此我們需要減少內存使用。 重新思考一下引入redis的目的。 redis像一個集合,整個業務就是驗證請求的參數是否在集合中。

 

這個結構就像洗澡的時候用的雙向閥門:左邊熱水,右邊冷水。大部分的編程語言都內置了filter。 拿python舉例,filter函數用于過濾序列, 過濾掉不符合條件的元素,返回由符合條件元素組成的列表。

我們看個例子:

  1. $ python2 
  2. Python 2.7.10 (default, Oct 6 2017, 22:29:07) 
  3. [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin 
  4. Type "help""copyright""credits" or "license" for more information. 
  5. >>> s = {2, 4} 
  6. >>> filter(lambda x:x in s, [0, 1, 2]) 
  7. [2] 

集合s中存在 2,4兩個數字,我們需要查詢 0,1,2 那些在集合s中。 lambda x:x in s構造一個匿名函數,判斷入參x是否在集合s中。 過濾器filter依次對列表中的數字執行匿名函數。最終返回列表[2]。

redis中實現set用了兩種結構:intset和hash table。 非數字或者大量數字時都會退化成hash table。 那么是否好的算法可以節省hash table的大小呢?

其實早在1970年由Burton Howard Bloom提出的布隆過濾器(英語:Bloom Filter)。 它實際上是一個很長的二進制向量和一系列隨機映射函數。 布隆過濾器可以用于檢索一個元素是否在一個集合中。 它的優點是空間效率和查詢時間都遠遠超過一般的算法, 缺點是有一定的誤識別率和刪除困難。

BloomFilter原理

我們常見的將業務字段拼接之后md5,放在一個集合中。 md5生成一個固定長度的128bit的串。 如果我們用bitmap來表示,則需要

  1. 2**128 = 340282366920938463463374607431768211456 bit 

判斷一個值在不在,就變成在這個bitmap中判斷所在位是否為1。 但是我們全世界的機器存儲空間也無法存儲下載。 因此我們只能分配有限的空間來存儲。 比如:

  1. import crc32 
  2. def BloomFilter(sample, size, hash_size=1): 
  3.  # 構造一個hash函數,將輸入數據散列到size一個位置上 
  4.  hash = lambda x:crc32(str(x).encode())%size 
  5.  collision, s = 0, set() 
  6.  for i in range(sample): 
  7.  k = set() 
  8.  for j in range(hash_size): 
  9.  k.add(hash(i+j*size/hash_size)) 
  10.  # 只有所有散列結果k都在s中,才認為i重復 
  11.  if not k - s: 
  12.  collision += 1 
  13.  continue 
  14.  # 將散列結果k更新到集合s中 
  15.  s |= k 
  16.  return collision 

當只有一個hash函數時:很容易發生沖突。

 

可以看到上面1和2的hash結果都是7,發生沖突。 如果增加hash函數,會發生什么情況?

 

我們使用更多的hash函數和更大的數據集合來測試。得到下面這張表

 

由此可以看到當增加hash方法能夠有效的降低碰撞機率。 比較好的數據如下:

 

Redis 布隆過濾器實戰「緩存擊穿、雪崩效應」

 

但是增加了hash方法之后,會降低空間的使用效率。當集合占用總體空間達到25%的時候, 增加hash 的效果已經不明顯

 

上面的使用多個hash方法來降低碰撞就是BloomFilter的核心思想。

適合的場景

  • 數據庫防止穿庫 Google Bigtable,Apache HBase和Apache Cassandra以及Postgresql 使用BloomFilter來減少不存在的行或列的磁盤查找。避免代價高昂的磁盤查找會大大提高數據庫查詢操作的性能。 如同一開始的業務場景。如果數據量較大,不方便放在緩存中。需要對請求做攔截防止穿庫。
  • 緩存宕機 緩存宕機的場景,使用布隆過濾器會造成一定程度的誤判。原因是除了Bloom Filter 本身有誤判率,宕機之前的緩存不一定能覆蓋到所有DB中的數據,當宕機后用戶請求了一個以前從未請求的數據,這個時候就會產生誤判。當然,緩存宕機時使用布隆過濾器作為應急的方式,這種情況應該也是可以忍受的。
  • WEB攔截器 相同請求攔截防止被侵入。用戶初次請求,將請求參數放入BloomFilter中,當第二次請求時,先判斷請求參數是否被BloomFilter擊中。可以提高緩存擊中率。
  • 惡意地址檢測 chrome 瀏覽器檢查是否是惡意地址。 首先針對本地BloomFilter檢查任何URL,并且僅當BloomFilter返回肯定結果時才對所執行的URL進行全面檢查(并且用戶警告,如果它也返回肯定結果)。
  • 比特幣加速 bitcoin 使用BloomFilter來加速錢包同步。

算法優點:

  • 數據空間小,不用存儲數據本身。

算法本身缺點:

  • 元素可以添加到集合中,但不能被刪除。
  • 匹配結果只能是“絕對不在集合中”,并不能保證匹配成功的值已經在集合中。
  • 當集合快滿時,即接近預估大容量時,誤報的概率會變大。
  • 數據占用空間放大。一般來說,對于1%的誤報概率,每個元素少于10比特,與集合中的元素的大小或數量無關。 - 查詢過程變慢,hash函數增多,導致每次匹配過程,需要查找多個位(hash個數)來確認是否存在。

對于BloomFilter的優點來說,缺點都可以忽略。畢竟只需要kN的存儲空間就能存儲N個元素。空間效率十分優秀。

如何使用BloomFilter

BloomFilter 需要一個大的bitmap來存儲。鑒于目前公司現狀,合適的存儲容器是redis。

redis集成BloomFilter方案:

redis集成BloomFilter方案:

  • 原生python 調用setbit 構造 BloomFilter
  • lua腳本
  • Rebloom - Bloom Filter Module for Redis (注:redis Module在redis4.0引入)
  • 使用hiredis 調用redis pyreBloom

原生python 方法太慢,lua腳本和module 部署比較麻煩。于是我們推薦使用pyreBloom,底層使用。

  1. pyreBloom:master λ ls 
  2. Makefile bloom.h bloom.pxd murmur.c pyreBloom.pyx 
  3. bloom.c bloom.o main.c pyreBloom.c 

從文件命名上可以看到bloom 使用c編寫。pyreBloom 使用cython編寫。

bloom.h 里面實現BloomFilter的核心邏輯,完成與redis server的交互;hash函數;添加,檢查和刪除方法的實現。

  1. int init_pyrebloom(pyrebloomctxt * ctxt, char * key, uint32_t capacity, double error, char* host, uint32_t port, charpassword, uint32_t db); 
  2. int free_pyrebloom(pyrebloomctxt * ctxt); 
  3. int add(pyrebloomctxt * ctxt, const char * data, uint32_t len); 
  4. int add_complete(pyrebloomctxt * ctxt, uint32_t count); 
  5. int check(pyrebloomctxt * ctxt, const char * data, uint32_t len); 
  6. int check_next(pyrebloomctxt * ctxt); 
  7. int delete(pyrebloomctxt * ctxt); 

pyreBloom.pyx

  1. import math 
  2. import random 
  3. cimport bloom 
  4. class pyreBloomException(Exception): 
  5.     '''Some sort of exception has happened internally''' 
  6.     pass 
  7. cdef class pyreBloom(object): 
  8.     cdef bloom.pyrebloomctxt context 
  9.     cdef bytes key 
  10.     property bits: 
  11.         def __get__(self): 
  12.             return self.context.bits 
  13.     property hashes: 
  14.         def __get__(self): 
  15.             return self.context.hashes 
  16.     def __cinit__(self, key, capacity, error, host='127.0.0.1', port=6379, 
  17.         password='', db=0): 
  18.         self.key = key 
  19.         if bloom.init_pyrebloom(&self.context, self.key, capacity, 
  20.             error, host, port, password, db): 
  21.             raise pyreBloomException(self.context.ctxt.errstr) 
  22.     def __dealloc__(self): 
  23.         bloom.free_pyrebloom(&self.context) 
  24.     def delete(self): 
  25.         bloom.delete(&self.context) 
  26.     def put(self, value): 
  27.         if getattr(value, '__iter__'False): 
  28.             r = [bloom.add(&self.context, v, len(v)) for v in value] 
  29.             r = bloom.add_complete(&self.context, len(value)) 
  30.         else
  31.             bloom.add(&self.context, value, len(value)) 
  32.             r = bloom.add_complete(&self.context, 1) 
  33.         if r < 0: 
  34.             raise pyreBloomException(self.context.ctxt.errstr) 
  35.         return r 
  36.     def add(self, value): 
  37.         return self.put(value) 
  38.     def extend(self, values): 
  39.         return self.put(values
  40.     def contains(self, value): 
  41.         # If the object is 'iterable'... 
  42.         if getattr(value, '__iter__'False): 
  43.             r = [bloom.check(&self.context, v, len(v)) for v in value] 
  44.             r = [bloom.check_next(&self.context) for i in range(len(value))] 
  45.             if (min(r) < 0): 
  46.                 raise pyreBloomException(self.context.ctxt.errstr) 
  47.             return [v for v, included in zip(value, r) if included] 
  48.         else
  49.             bloom.check(&self.context, value, len(value)) 
  50.             r = bloom.check_next(&self.context) 
  51.             if (r < 0): 
  52.                 raise pyreBloomException(self.context.ctxt.errstr) 
  53.             return bool(r) 
  54.     def __contains__(self, value): 
  55.         return self.contains(value) 
  56.     def keys(self): 
  57.         '''Return a list of the keys used in this bloom filter''' 
  58.         return [self.context.keys[i] for i in range(self.context.num_keys)] 
  59. 原生pyreBloom方法: 
  60. cdef class pyreBloom(object): 
  61.  cdef bloom.pyrebloomctxt context 
  62.  cdef bytes 
  63.  property bits: 
  64.  property hashes: 
  65.  // 使用的hash方法數 
  66.  def delete(self): 
  67.  // 刪除,會在redis中刪除 
  68.  def put(self, value): 
  69.  // 添加 底層方法, 不建議直接調用 
  70.  def add(self, value): 
  71.  // 添加單個元素,調用put方法 
  72.  def extend(self, values): 
  73.  // 添加一組元素,調用put方法 
  74.  def contains(self, value): 
  75.  // 檢查是否存在,當`value`可以迭代時,返回`[value]`, 否則返回`bool` 
  76.  def keys(self): 
  77.  // 在redis中存儲的key列表 

由于pyreBloom使用hiredis庫,本身沒有重連等邏輯,于是錯了簡單的封裝。

  1. # coding=utf-8 
  2. ''
  3. bloom filter 基礎模塊 
  4. 可用方法: 
  5. extend, keys, containsadd, put, hashes, bits, delete 
  6. 使用方法: 
  7. >>> class TestModel(BaseModel): 
  8. ... PREFIX = "bf:test" 
  9. >>> t = TestModel() 
  10. >>> t.add('hello'
  11. >>> t.extend(['hi''world']) 
  12. >>> t.contains('hi'
  13. True 
  14. >>> t.delete() 
  15. ''
  16. import logging 
  17. from six import PY3 as IS_PY3 
  18. from pyreBloom import pyreBloom, pyreBloomException 
  19. from BloomFilter.utils import force_utf8 
  20. class BaseModel(object): 
  21. ''
  22. bloom filter 基礎模塊 
  23. 參數: 
  24. SLOT: 可用方法類型 
  25. PREFIX: redis前綴 
  26. BF_SIZE: 
  27. BF_ERROR: 允許的出錯率 
  28. RETRIES: 連接重試次數 
  29. host: redis 服務器IP 
  30. port: redis 服務器端口 
  31. db: redis 服務器DB 
  32. _bf_conn: 內部保存`pyreBloom`實例 
  33. ''
  34. SLOT = {'add''contains''extend''keys''put''delete'
  35. 'bits''hashes'
  36. PREFIX = "" 
  37. BF_SIZE = 100000 
  38. BF_ERROR = 0.01 
  39. RETRIES = 2 
  40. def __init__(self, redis=None): 
  41. ''
  42. 初始化redis配置 
  43. :param redis: redis 配置 
  44. ''
  45. # 這里初始化防止類靜態變量多個繼承類復用,導致數據被污染 
  46. self._bf_conn = None 
  47. self._conf = { 
  48. 'host''127.0.0.1''password'''
  49. 'port': 6379, 'db': 0 
  50. if redis: 
  51. for k, v in redis.items(): 
  52. if k in self._conf: 
  53. self._conf[k] = redis[k] 
  54. self._conf = force_utf8(self._conf) 
  55. @property 
  56. def bf_conn(self): 
  57. ''
  58. 初始化pyreBloom 
  59. ''
  60. if not self._bf_conn: 
  61. prefix = force_utf8(self.PREFIX) 
  62. logging.debug( 
  63. 'pyreBloom connect: redis://%s:%s/%s, (%s %s %s)'
  64. self._conf['host'], self._conf['port'], self._conf['db'], 
  65. prefix, self.BF_SIZE, self.BF_ERROR, 
  66. self._bf_conn = pyreBloom( 
  67. prefix, self.BF_SIZE, self.BF_ERROR, **self._conf) 
  68. return self._bf_conn 
  69. def __getattr__(self, method): 
  70. '''調用pyrebloom方法 
  71. 沒有枚舉的方法將從`pyreBloom`中獲取 
  72. :param method: 
  73. :return: pyreBloom.{method} 
  74. ''
  75. # 只提供內部方法 
  76. if method not in self.SLOT: 
  77. raise NotImplementedError() 
  78. # 捕獲`pyreBloom`的異常, 打印必要的日志 
  79. def catch_error(*a, **kwargs): 
  80. '''多次重試服務''' 
  81. args = force_utf8(a) 
  82. kwargs = force_utf8(kwargs) 
  83. for _ in range(self.RETRIES): 
  84. try: 
  85. func = getattr(self.bf_conn, method) 
  86. res = func(*args, **kwargs) 
  87. # python3 返回值和python2返回值不相同, 
  88. # 手工處理返回類型 
  89. if method == 'contains' and IS_PY3: 
  90. if isinstance(res, list): 
  91. return [i.decode('utf8'for i in res] 
  92. return res 
  93. except pyreBloomException as error: 
  94. logging.warn( 
  95. 'pyreBloom Error: %s %s', method, str(error)) 
  96. self.reconnect() 
  97. if _ == self.RETRIES: 
  98. logging.error('pyreBloom Error'
  99. raise error 
  100. return catch_error 
  101. def __contains__(self, item): 
  102. '''跳轉__contains__方法 
  103. :param item: 查詢元素列表/單個元素 
  104. :type item: list/basestring 
  105. :return: [bool...]/bool 
  106. ''
  107. return self.contains(item) 
  108. def reconnect(self): 
  109. ''
  110. 重新連接bloom 
  111. `pyreBloom` 連接使用c driver,沒有提供timeout參數,使用了內置的timeout 
  112. 同時為了保證服務的可靠性,增加了多次重試機制。 
  113. struct timeval timeout = { 1, 5000 }; 
  114. ctxt->ctxt = redisConnectWithTimeout(host, port, timeout); 
  115. del self._bf_conn 會調用`pyreBloom`內置的C的del方法,會關閉redis連接 
  116. ''
  117. if self._bf_conn: 
  118. logging.debug('pyreBloom reconnect'
  119. del self._bf_conn 
  120. self._bf_conn = None 
  121. _ = self.bf_conn 

進階:計數過濾器(Counting Filter)

提供了一種在BloomFilter上實現刪除操作的方法,而無需重新重新創建過濾器。在計數濾波器中,陣列位置(桶)從單個位擴展為n位計數器。實際上,常規布隆過濾器可以被視為計數過濾器,其桶大小為一位。

插入操作被擴展為遞增桶的值,并且查找操作檢查每個所需的桶是否為非零。然后,刪除操作包括遞減每個桶的值。

存儲桶的算術溢出是一個問題,并且存儲桶應該足夠大以使這種情況很少見。如果確實發生,則增量和減量操作必須將存儲區設置為最大可能值,以便保留BloomFilter的屬性。

計數器的大小通常為3或4位。因此,計算布隆過濾器的空間比靜態布隆過濾器多3到4倍。相比之下, Pagh,Pagh和Rao(2005)以及Fan等人的數據結構。(2014)也允許刪除但使用比靜態BloomFilter更少的空間。

計數過濾器的另一個問題是可擴展性有限。由于無法擴展計數布隆過濾器表,因此必須事先知道要同時存儲在過濾器中的最大鍵數。一旦超過表的設計容量,隨著插入更多密鑰,誤報率將迅速增長。

Bonomi等人。(2006)引入了一種基于d-left散列的數據結構,它在功能上是等效的,但使用的空間大約是計算BloomFilter的一半。此數據結構中不會出現可伸縮性問題。一旦超出設計容量,就可以將密鑰重新插入到雙倍大小的新哈希表中。

Putze,Sanders和Singler(2007)的節省空間的變體也可用于通過支持插入和刪除來實現計數過濾器。

Rottenstreich,Kanizo和Keslassy(2012)引入了一種基于變量增量的新通用方法,該方法顯著提高了計算布隆過濾器及其變體的誤報概率,同時仍支持刪除。與計數布隆過濾器不同,在每個元素插入時,散列計數器以散列變量增量而不是單位增量遞增。要查詢元素,需要考慮計數器的確切值,而不僅僅是它們的正面性。如果由計數器值表示的總和不能由查詢元素的相應變量增量組成,則可以將否定答案返回給查詢。

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2024-01-05 09:04:35

隆過濾器數據結構哈希函數

2022-03-21 08:31:07

布隆過濾器Redis過濾器原理

2025-04-30 08:47:41

2024-03-15 11:21:22

布隆過濾器數據庫數據

2024-01-22 04:00:00

2024-11-04 08:45:48

布隆過濾器元數據指紋值

2024-09-18 10:08:37

2023-04-26 08:32:45

Redis布隆過濾器

2025-02-08 17:30:00

布隆過濾器數據結構

2023-01-31 08:19:53

二進制元素數量

2020-10-29 07:16:26

布隆過濾器場景

2020-03-16 14:57:24

Redis面試雪崩

2019-10-12 14:19:05

Redis數據庫緩存

2023-03-10 13:33:00

緩存穿透緩存擊穿緩存雪崩

2024-09-25 17:44:08

2025-01-23 00:00:00

Java布隆過濾器

2021-09-03 06:33:24

布隆過濾器高并發

2024-10-09 15:54:38

布隆過濾器函數

2025-01-22 00:00:00

布隆過濾器二進制

2021-06-05 09:01:01

Redis緩存雪崩緩存穿透
點贊
收藏

51CTO技術棧公眾號

亚洲一区二区中文| 精品国产欧美一区二区五十路 | 婷婷激情小说网| www.在线视频| 91在线观看高清| 国产欧美婷婷中文| 激情综合网五月婷婷| 国产成人精品免费视| 777精品伊人久久久久大香线蕉| 成人一区二区av| 欧美少妇另类| 国产福利91精品| 国产精品aaa| 免费在线观看黄视频| 亚洲动漫在线观看| 6080日韩午夜伦伦午夜伦| 7777在线视频| 国产小视频在线播放| 国产成人综合在线观看| 国产激情久久久久| 久久精品国产av一区二区三区| 国产一区二区三区日韩精品| 欧美v国产在线一区二区三区| 免费观看日韩毛片| 在线免费观看污| 国产色产综合产在线视频| 成人91免费视频| 中文字幕免费高清在线观看| 国产欧美在线| 欧美成人精品激情在线观看| 国产美女免费无遮挡| 1313精品午夜理伦电影| 欧美日韩国产在线观看| 久久久久久久久久久视频| dj大片免费在线观看| 国产农村妇女精品| 欧美精品尤物在线| 视频二区在线观看| 风间由美性色一区二区三区| 国产日韩欧美自拍| 色老头在线视频| 亚洲在线观看| 91av国产在线| 国产一级久久久| 欧美激情视频一区二区三区在线播放| 中文字幕精品av| 91网站免费视频| 日韩极品少妇| 亚洲精选一区二区| 美女又爽又黄视频毛茸茸| jizz久久精品永久免费| 日韩午夜电影在线观看| 色偷偷中文字幕| 亚洲91在线| 欧美精品视频www在线观看| 成人性生生活性生交12| 色综合天天色| 欧美综合欧美视频| 538在线视频观看| **在线精品| 一本色道久久综合亚洲aⅴ蜜桃| 三上悠亚久久精品| 国内激情视频在线观看| 五月天中文字幕一区二区| 国产精品久久国产| 国产亚av手机在线观看| 亚洲成人1区2区| 日韩伦理在线免费观看| 女海盗2成人h版中文字幕| 天天影视涩香欲综合网| www.四虎成人| 久久免费影院| 欧美一级国产精品| 亚洲成年人av| 香蕉久久99| 国产一区二区三区视频在线观看 | 精品国产av鲁一鲁一区| 国产一区二区三区不卡在线观看| 91久久久久久久久久久| 精品久久国产视频| 94色蜜桃网一区二区三区| 久久久亚洲综合网站| 你懂得网站在线| 国产精品美日韩| 好吊色视频988gao在线观看| 国产盗摄在线视频网站| 欧美日韩在线一区| 超碰在线人人爱| 欧美午夜在线播放| 亚洲精品不卡在线| 五月婷婷欧美激情| 中文字幕日韩欧美精品高清在线| 国产做受69高潮| 四虎影院在线免费播放| 激情国产一区二区 | 深爱五月激情五月| 国产欧美日韩麻豆91| 最新中文字幕久久| 女人高潮被爽到呻吟在线观看| 色老汉一区二区三区| 手机在线国产视频| 国内精品免费| 少妇精69xxtheporn| 成年人av电影| 性色一区二区| 91理论片午午论夜理片久久| 天天干在线观看| 中文字幕亚洲精品在线观看| 男人插女人视频在线观看| 国内精品伊人| 日韩www在线| 国产精品国产精品88| 136国产福利精品导航网址| 国产精品久久久久久久久久免费| 亚洲高清视频在线播放| 中文字幕欧美国产| 欧美亚洲国产成人| 亚洲精品高潮| 日韩在线视频观看正片免费网站| 亚洲免费激情视频| 国产在线精品不卡| 欧美美乳视频网站在线观看| 青青草视频在线免费直播| 欧美午夜在线一二页| 成人免费毛片日本片视频| 外国成人激情视频| 国产成人精品久久| 同心难改在线观看| 一区二区三区在线免费播放| 日本在线观看免费视频| 亚洲日产av中文字幕| 欧美极品美女电影一区| 国产又粗又猛又黄又爽无遮挡| 91亚洲国产成人精品一区二区三| 丁香色欲久久久久久综合网| 天天综合在线观看| 最近中文字幕mv在线一区二区三区四区 | 亚洲人成无码www久久久| 亚洲开心激情| 欧美大片va欧美在线播放| 亚洲天天综合网| 日本一区二区三区四区| 91视频 -- 69xx| 欧美一区自拍| 97色在线观看| 亚洲人在线观看视频| 亚洲不卡av一区二区三区| 麻豆av免费看| 黄色成人av网站| 99精彩视频| 国产美女一区视频| 欧美tickling挠脚心丨vk| 日本老熟俱乐部h0930| 国产成人在线看| 日韩欧美一级在线| 中文字幕区一区二区三| 久久久久久久久91| 人妻无码中文字幕| 午夜电影网亚洲视频| 午夜视频在线观看国产| 99热在线精品观看| 久久影院理伦片| 少妇一区视频| 日韩视频第一页| 国产农村妇女毛片精品| 亚洲男帅同性gay1069| 日本少妇激三级做爰在线| 综合国产精品| 国产精品区免费视频| 九色porny丨首页入口在线| 亚洲另类xxxx| 中文字幕乱码在线观看| 亚洲男人的天堂在线aⅴ视频| 999久久久精品视频| 欧美不卡在线| 久久久久无码国产精品一区| 欧美日韩国产v| 日韩在线观看精品| 精品人妻无码一区二区三区蜜桃一| 夜夜嗨av一区二区三区四季av | 粉嫩久久久久久久极品| 午夜精品蜜臀一区二区三区免费| 四虎成人免费在线| 在线观看日韩毛片| 精品欧美一区二区久久久久| 不卡一区在线观看| 国产一级不卡毛片| 在线精品视频在线观看高清| 国产一级特黄a大片99| 伊伊综合在线| 精品国偷自产在线视频| 亚洲欧美强伦一区二区| 日韩欧美一区二区三区| 欧美特级一级片| 91在线视频网址| 永久免费的av网站| 亚洲国产免费| 亚洲五月六月| 超碰97久久| 国产美女直播视频一区| 91桃色在线观看| 色妞一区二区三区| 天天干天天插天天操| 欧美日韩国产在线播放网站| 欧美亚韩一区二区三区| 日韩毛片在线免费观看| 亚洲天堂视频一区| 国产suv精品一区二区6| 北条麻妃在线视频| 激情成人亚洲| 国产成年人在线观看| 亚洲精品动态| 草莓视频一区| 亚洲精品伦理| 欧美亚洲伦理www| 50度灰在线| 少妇av一区二区三区| 亚洲色偷精品一区二区三区| 欧美一级高清片| 中文字幕av无码一区二区三区| 亚洲国产精品久久艾草纯爱| 精品视频第一页| 久久伊人蜜桃av一区二区| 捷克做爰xxxⅹ性视频| 男男成人高潮片免费网站| 欧美 日本 亚洲| 欧美午夜一区二区福利视频| 一区二区不卡在线| 欧美中文字幕一区二区| 欧美成ee人免费视频| 农村少妇一区二区三区四区五区| 亚洲一区二区三区四区视频| 久久天堂影院| 国产精品美女网站| 偷拍精品精品一区二区三区| 777国产偷窥盗摄精品视频| 青青青国内视频在线观看软件| 国产亚洲精品免费| 九九久久综合网站| 啊v在线视频| 亚洲欧美综合图区| 日本a一级在线免费播放| 日韩成人激情在线| 天堂av资源在线| 亚洲福利视频二区| 国产91免费在线观看| 精品免费99久久| 成人无码一区二区三区| 精品少妇一区二区三区在线视频| 99热这里只有精品5| 日韩三级在线观看| 性做久久久久久久| 精品国产免费人成电影在线观看四季| 国产夫绿帽单男3p精品视频| 欧美成人伊人久久综合网| 亚洲va欧美va| 亚洲成人av资源网| 少妇性bbb搡bbb爽爽爽欧美| 亚洲片av在线| 在线激情小视频| 超碰91人人草人人干| 色www永久免费视频首页在线| 欧美激情精品久久久| √最新版天堂资源网在线| 18久久久久久| 精品国模一区二区三区| 国产欧美精品一区二区| 亚洲狼人综合| 国产亚洲一区二区三区在线播放 | 奇米影视一区二区三区小说| 艹b视频在线观看| 精品系列免费在线观看| 久久久久久久久久影视| 久久视频一区二区| 激情无码人妻又粗又大| 一区二区三区精品视频| 午夜精品久久久久久久久久久久久蜜桃| 疯狂蹂躏欧美一区二区精品| 波多野结衣在线观看视频| 欧美精品18+| 国产综合视频在线| 日韩麻豆第一页| 亚洲第一页视频| 亚洲另类激情图| 高清国产福利在线观看| 欧美另类极品videosbestfree| 日本片在线看| 国产精品福利久久久| 亚洲久草在线| 国产视色精品亚洲一区二区| 成人3d精品动漫精品一二三| 2021国产视频| 国产精品一页| 黄色三级视频在线播放| 成人黄色av电影| 亚洲第一香蕉网| 一区二区三区高清| √资源天堂中文在线| 欧美亚洲综合在线| www.久久久久久| 国产丝袜精品第一页| 四虎影院观看视频在线观看| 国内揄拍国内精品| 日本欧美韩国| 国产久一道中文一区| 九九热爱视频精品视频| 在线观看日本一区| 天堂在线亚洲视频| 91在线第一页| 26uuu国产在线精品一区二区| 很污很黄的网站| 激情懂色av一区av二区av| 国产精品久久777777换脸| 日韩精品在线免费观看| 免费在线观看av| 欧美在线播放视频| 精品欧美视频| 久久综合九九| 韩日在线一区| 一区二区在线免费看| 久久日韩精品一区二区五区| 亚洲天堂黄色片| 在线视频综合导航| 日本福利片高清在线观看| 久久亚洲成人精品| 26uuu亚洲电影| 国产一区二区三区四区五区在线| 欧美电影免费| 在线观看的毛片| 久久综合精品国产一区二区三区 | 五月婷婷综合网| aaa一区二区| 日韩在线视频一区| 国产一区二区三区四区五区3d| 精品视频第一区| 一本色道久久综合| 九色91porny| 国产精品美女一区二区三区 | 国产区在线观看| 国产精品视频永久免费播放| 欧美三级午夜理伦三级小说| 久艹在线免费观看| 国产一区二区三区久久悠悠色av| 99久久99久久精品免费| 精品视频一区三区九区| 黄色av网站在线| 国产精品高精视频免费| 一本久久青青| 干日本少妇首页| 久久久99久久| 日韩欧美大片在线观看| 制服丝袜亚洲播放| 国产精品一区二区三区视频网站| 国产在线精品播放| 成人vr资源| 午夜两性免费视频| 日本一区二区三区久久久久久久久不| 国产又大又黑又粗免费视频| 亚洲欧美另类人妖| 欧美日韩免费看片| 亚洲欧美影院| 黄网站免费久久| 成人免费视频国产免费观看| 日韩精品在线网站| 男男gaygays亚洲| 久久久99国产精品免费| 亚洲欧洲一区二区天堂久久| 亚洲美女精品视频| 欧美日韩在线视频一区| 午夜小视频免费| 国产精品欧美日韩久久| 第一社区sis001原创亚洲| 黄色手机在线视频| 一区二区三区蜜桃网| 成人av无码一区二区三区| 国模私拍一区二区三区| 香蕉国产成人午夜av影院| 成人免费视频久久| 亚洲日本欧美天堂| 性生交生活影碟片| 欧美中文在线观看| 精品国产一区探花在线观看| 天天干天天色天天干| 亚洲综合在线免费观看| 天堂av资源在线| 91成人福利在线| 久久99国内| 午夜免费福利视频在线观看| 香蕉影视欧美成人| 你懂的在线看| 亚洲综合在线小说| 亚洲在线免费| 日本女人性生活视频| 日韩精品一区国产麻豆| eeuss鲁一区二区三区| 亚洲精品永久www嫩草| 国产成人在线视频播放| 丰满人妻一区二区三区四区| 久久天天躁狠狠躁夜夜av| 天海翼精品一区二区三区|