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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Rocksdb 通过posix_advise 让内核减少在page_cache的预读

發(fā)布時(shí)間:2023/11/27 生活经验 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Rocksdb 通过posix_advise 让内核减少在page_cache的预读 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1. 問題排查
      • 確認(rèn)I/O完全/大多數(shù)來自于rocksdb
      • 確認(rèn)此時(shí)系統(tǒng)只使用了rocksdb的Get來讀
      • 確認(rèn)每次系統(tǒng)調(diào)用下發(fā)讀的請(qǐng)求大小
      • 確認(rèn)是否在內(nèi)核發(fā)生了預(yù)讀
    • 2. 問題原因
      • 內(nèi)核預(yù)讀機(jī)制
      • page_cache_sync_readahead
      • ondemand_readahead
    • 3. 優(yōu)化

事情起源于 組內(nèi)的分布式kv 系統(tǒng)使用rocksdb過程中發(fā)現(xiàn)磁盤有超過預(yù)期3-4x的讀I/O問題,因?yàn)榻沽薭lock-cache,也就是每一次Get會(huì)對(duì)應(yīng)一次磁盤I/O,剛好上層Get的qps和下層磁盤的r/s 基本吻合,也就是一次讀,讀了超過3個(gè)page。但是實(shí)際寫入的value也就 128B,按照nvme的block size 4K的配置,讀上來3個(gè)page則遠(yuǎn)超過了我們的預(yù)期。

本文涉及的代碼 rocksdb版本是 6.4.6,linux 內(nèi)核版本是 3.10.1

1. 問題排查

看到了嚴(yán)重的讀放大現(xiàn)象之后,接下來一探問題的原因。

確認(rèn)I/O完全/大多數(shù)來自于rocksdb

當(dāng)我們不知道kv系統(tǒng)內(nèi)部如何使用rocksdb的情況下需要確認(rèn)這一些IO的來源。

  1. 抓I/O 線程棧

    • sudo iotop 能直接看到系統(tǒng)中的磁盤i/o來源的線程

      如果此時(shí)能夠看到具體的線程名稱,確認(rèn)是在讀rocksdb,OK,跳過這一步

    • sudo pstack tid抓取一個(gè)線程棧

      pstack的邏輯是通過gdb attach進(jìn)去 執(zhí)行bt,多抓幾次就能夠知道I/O線程大多數(shù)的時(shí)間在干嘛

      這里發(fā)現(xiàn)確實(shí)是在rocksdb的Get調(diào)用棧上

      Thread 1 (process 1201132):
      #0  0x00007fa59de53f73 in pread64 () from /lib64/libpthread.so.0
      #1  0x00000000009020c3 in pread (__offset=56899894, __nbytes=3428, __buf=0x7fa4a83bb670, __fd=<optimized out>) at /usr/include/bits/unistd.h:83
      #2  rocksdb::PosixRandomAccessFile::Read(unsigned long, unsigned long, rocksdb::IOOptions const&, rocksdb::Slice*, char*, rocksdb::IODebugContext*) const () at thirdpartty/rocksdb/env/io_posix.cc:453
      #3  0x0000000000a074f7 in rocksdb::RandomAccessFileReader::Read(unsigned long, unsigned long, rocksdb::Slice*, char*, bool) const () at thirdpartty/rocksdb/monitoring/statistics.h:127
      #4  0x000000000097b8e9 in rocksdb::BlockFetcher::ReadBlockContents() () at thirdpartty/rocksdb/table/format.h:45
      #5  0x000000000095bd87 in rocksdb::BlockBasedTable::MaybeReadBlockAndLoadToCache<rocksdb::Block> (this=0xf2083e80, prefetch_buffer=0x0, ro=..., handle=..., uncompression_dict=..., block_entry=0x7fa4a83bcc10, block_type=rocksdb::kData, get_context=0x7fa4a83bd630, lookup_context=0x7fa4a83bcf50, contents=0x0) at thirdpartty/rocksdb/include/rocksdb/cache.h:272
      #6  0x000000000095c1d1 in rocksdb::BlockBasedTable::RetrieveBlock<rocksdb::Block> (this=this@entry=0xf2083e80, prefetch_buffer=prefetch_buffer@entry=0x0, ro=..., handle=..., uncompression_dict=..., block_entry=0x7fa4a83bcc10, block_type=rocksdb::kData, get_context=0x7fa4a83bd630, lookup_context=0x7fa4a83bcf50, for_compaction=false, use_cache=true) at thirdpartty/rocksdb/table/block_based/block_based_table_reader.h:585
      #7  0x000000000095ef3a in rocksdb::BlockBasedTable::NewDataBlockIterator<rocksdb::DataBlockIter> (this=this@entry=0xf2083e80, ro=..., handle=..., input_iter=input_iter@entry=0x7fa4a83bd190, block_type=block_type@entry=rocksdb::kData, get_context=get_context@entry=0x7fa4a83bd630, lookup_context=0x7fa4a83bcf50, s=..., prefetch_buffer=0x0, for_compaction=false) at thirdpartty/rocksdb/monitoring/perf_step_timer.h:41
      #8  0x000000000096a4a1 in rocksdb::BlockBasedTable::Get(rocksdb::ReadOptions const&, rocksdb::Slice const&, rocksdb::GetContext*, rocksdb::SliceTransform const*, bool) () at thirdpartty/rocksdb/table/block_based/block_based_table_reader.cc:3288
      #9  0x00000000008a1c0c in rocksdb::TableCache::Get(rocksdb::ReadOptions const&, rocksdb::InternalKeyComparator const&, rocksdb::FileMetaData const&, rocksdb::Slice const&, rocksdb::GetContext*, rocksdb::SliceTransform const*, rocksdb::HistogramImpl*, bool, int) () at thirdpartty/rocksdb/db/table_cache.cc:406
      
  2. 抓取進(jìn)程都在操作哪一些文件,和上面的進(jìn)程棧信息double check一下
    這里需要系統(tǒng)支持eBPF,使用了一個(gè)bcc工具集中的一個(gè)opensnoop命令。

    opensnoop -p pid 能夠看到當(dāng)前進(jìn)程按順序操作的文件,都會(huì)打印出來

    # opensnoop -p 1200034|grep sst
    1200034 rocksdb:low3     6929   0 ../db/13/064388.sst
    1200034 rocksdb:low3     14988   0 ../db/13/064389.sst
    1200034 rocksdb:low3     18074   0 ../db/13/064390.sst
    1200034 rocksdb:low12    3158   0 ../db/11/064350.sst
    1200034 rocksdb:low0     9030   0 ../db/31/064494.sst
    1200034 rocksdb:low1     10111   0 ../db/19/064495.sst
    1200034 rocksdb:low2     1691   0 ../db/0/064570.sst
    1200034 test_process/w4-  2879   0 00000000001494113842.sst
    1200034 rocksdb:low10    1974   0 ../db/7/064437.sst
    1200034 rocksdb:low4     3696   0 ../db/14/064445.sst
    1200034 rocksdb:low12    3158   0 ../db/11/064351.sst
    1200034 rocksdb:low11    3017   0 ../db/21/064524.sst
    

    可以看到除了rocksdb的sst文件之外,還有一個(gè)其他的文件,但是我們主體的讀取都是sst,所以基本能夠確認(rèn)磁盤的讀i/o都是來源于rocksdb.

確認(rèn)此時(shí)系統(tǒng)只使用了rocksdb的Get來讀

到這里,我們能夠確認(rèn)I/O是由rocksdb產(chǎn)生的,可能會(huì)想是不是kv系統(tǒng)中使用rocksdb的方式有問題,他們可能不僅僅是用了Get,在某一個(gè)他們也不清楚的線程里用了迭代器掃描,才產(chǎn)生這么多的I/O,我們想要確認(rèn)這個(gè)問題。這個(gè)時(shí)候之前使用的pstack調(diào)用棧就不夠用了,因?yàn)樗皇且粋€(gè)線程,而我們要用它抓更多的線程比較麻煩,簡單且直觀的辦法就是火焰圖。

現(xiàn)在有大量的I/O,而且rocksdb的操作基本都是on-cpu的,所以直接看on-cpu的火焰圖就非常容易得看到IO調(diào)用棧的來源了。

通過如下腳本立即抓取

#!/bin/sh
DIR=./git clone https://github.com/brendangregg/FlameGraph # clone 火焰圖目錄
if [ $? -ne 0 ]; thenecho "clone FlameGraph failed"exit -1
ficd FlameGraph
sudo perf record -F 99 -p $1 -g -o $DIR/"$1".data -- sleep $2
sudo perf script -i $DIR/"$1".data > $DIR/"$1".perf
stackcollapse-perf.pl $DIR/"$1".perf > $DIR/"$1".folded
flamegraph.pl $DIR/"$1".folded > $DIR/"$1".svgcp $DIR/cpu1.svg ../

會(huì)在當(dāng)前目錄下生成一個(gè)$pid.svg的文件,使用瀏覽器打開即可看到完整的on-cpu調(diào)用棧

看起來確實(shí)是大多數(shù)的cpu都消耗在了rocksdb的Get調(diào)用棧上了,好吧。。。問題躲不開了。

確認(rèn)每次系統(tǒng)調(diào)用下發(fā)讀的請(qǐng)求大小

按照我們對(duì)磁盤讀取的正常邏輯理解,如果讀取的數(shù)據(jù)塊大小小于正常的磁盤塊4k大小的話 從磁盤文件系統(tǒng)下發(fā)的讀取請(qǐng)求會(huì)填充成一個(gè)4k的cache頁面,讀取一個(gè)磁盤的block。

所以為什么它這里會(huì)讀取這么多的block,估算上層的總磁盤帶寬/總qps 可以得到每個(gè)請(qǐng)求大概讀了3-4個(gè)block,而實(shí)際的value大小也就128B,讀取sst的時(shí)候會(huì)把這個(gè)value所在的datablock整個(gè)讀上來,默認(rèn)一個(gè)datablock是4k,這就很奇怪了。

為了確認(rèn)rocksdb側(cè)的pread64系統(tǒng)調(diào)用確實(shí)讀的內(nèi)容比較少,我們要獲取系統(tǒng)調(diào)用每次讀的請(qǐng)求大小,看是不是rocksdb 拼接的請(qǐng)求有問題。

執(zhí)行命令:sudo strace -ttt -T -F -p 1200034 -e trace=pread64 -o strace.txt 追蹤pread64系統(tǒng)調(diào)用,并打印每個(gè)系統(tǒng)調(diào)用的時(shí)間,最后的結(jié)果保存在strace.txt中。

1200069 1619615339.683332 pread64(3686,  <unfinished ...>
1200067 1619615339.683750 pread64(23901,  <unfinished ...>
1200064 1619615339.683761 pread64(6470,  <unfinished ...>
1200060 1619615339.683776 pread64(17541,  <unfinished ...>
1200058 1619615339.683784 pread64(15210,  <unfinished ...>
1200069 1619615339.686670 <... pread64 resumed> "\0\34\232\1abcdefghij2376553061\1\202\326\216X\0\0\0"..., 3941, 26362727) = 3941 <0.002925>
1200067 1619615339.686696 <... pread64 resumed> "\320\0\0\0\0\0\0\0\341\307\326\315\246I\0\0\6\24\0\0\0abcdefghij3"..., 3950, 30242502) = 3950 <0.002944>
1200064 1619615339.686711 <... pread64 resumed> "`\30\260\200\237\356\354\264\22\21\220\23\336%\0\0\0\0m-\323Y\0\0\0\0\320\0\0\0\0\0"..., 3422, 18387244) = 3422 <0.002949>
1200060 1619615339.686726 <... pread64 resumed> "\311\4\323\32\0\32\6abcdefghij46297319\21\377\377\377\377\377\377"..., 3941, 31861449) = 3941 <0.002948>
1200058 1619615339.686734 <... pread64 resumed> "7,<Qz p&~dHZ!i5kvVUU^Jgc%vA/F;uL"..., 3977, 15684275) = 3977 <0.002949>
...

如果想要確認(rèn)這個(gè)pread64讀的文件句柄是rocksdb的sst文件,可以通過 sudo ls -l /proc/1200034/fd/15210 來看這個(gè)進(jìn)程打開的文件句柄確實(shí)是連結(jié)到了sst文件。

通過上面抓到的pread64系統(tǒng)調(diào)用信息,可以很明顯的發(fā)現(xiàn)系統(tǒng)調(diào)用下發(fā)的是小于4K的請(qǐng)求大小。。。我擦嘞。

立即通過btrace再抓一下磁盤I/O:

$ sudo btrace -a read /dev/nvme0n1
259,0   32        1     0.000000000 1201042  Q  RA 5033391024 + 32 [test_process]
259,0   32        2     0.000001625 1201042  G  RA 5033391024 + 32 [test_process]
259,0   32        3     0.000001926 1201042  P   N [test_process]
259,0   32        4     0.000002279 1201042  U   N [test_process] 1
259,0   32        5     0.000003219 1201042  D  RA 5033391024 + 32 [test_process]
259,0   33        1     0.000010787 1201046  Q  RA 3397669536 + 24 [test_process]
259,0   33        2     0.000012535 1201046  G  RA 3397669536 + 32 [test_process]
259,0   33        3     0.000012992 1201046  P   N [test_process]
259,0   33        4     0.000013308 1201046  U   N [test_process] 1
259,0   33        5     0.000014375 1201046  D  RA 3397669536 + 32 [test_process]
259,0    3        1     0.000024160 1201030  Q  RA 32733208 + 32 [test_process]
259,0    3        2     0.000025016 1201030  G  RA 32733208 + 24 [test_process]
259,0    3        3     0.000025320 1201030  P   N [test_process]
259,0    3        4     0.000025660 1201030  U   N [test_process] 1
259,0    3        5     0.000026382 1201030  D  RA 32733208 + 32 [test_process]
259,0    3        6     0.000032077 843424  C  RA 5618458520 + 32 [0]
259,0   32        6     0.000067811 1201120  Q  RA 4936712824 + 32 [test_process]
259,0   32        7     0.000068510 1201120  G  RA 4936712824 + 32 [test_process]
...

可以看到確實(shí),從磁盤上讀到了很多超過2個(gè)4k的block,也就是系統(tǒng)調(diào)用pread64下發(fā)了小于一個(gè)block的請(qǐng)求,而落到磁盤的I/O達(dá)到了4個(gè)block。。。interesting。

確認(rèn)是否在內(nèi)核發(fā)生了預(yù)讀

只能進(jìn)入內(nèi)核邏輯了,看起來像是操作系統(tǒng)的預(yù)讀邏輯。

順著火焰圖的調(diào)用棧來看,我們的pread系統(tǒng)調(diào)用的調(diào)用棧如下:

sys_pread64vfs_readdo_sync_readxfs_file_aio_readxfs_file_buffered_aio_readgeneric_file_aio_readdo_generic_file_readpage_cache_sync_readahead

實(shí)際由page-cache下發(fā)讀取的頁面?zhèn)€數(shù)是在page_cache_sync_readahead 的參數(shù)中。

這里我們拋開內(nèi)核函數(shù)的邏輯,想要單純確認(rèn)一下do_generic_file_read下發(fā)的請(qǐng)求數(shù)目,可以通過stap來抓取一下這個(gè)函數(shù)的變量

void page_cache_sync_readahead(struct address_space *mapping,struct file_ra_state *ra, struct file *filp,pgoff_t offset, unsigned long req_size);#!/bin/stapprobe kernel.function("page_cache_sync_readahead").call {printf("req_size : %lu\n", $req_size);
}

可以發(fā)現(xiàn)page_cache_sync_readahead這個(gè)函數(shù)的時(shí)候僅僅才1個(gè)頁面。

繼續(xù)向下,看到page_cache_sync_readahead 內(nèi)部實(shí)現(xiàn)有兩個(gè)分支:

void page_cache_sync_readahead(struct address_space *mapping,struct file_ra_state *ra, struct file *filp,pgoff_t offset, unsigned long req_size)
{/* no read-ahead */if (!ra->ra_pages)return;/* be dumb */if (filp && (filp->f_mode & FMODE_RANDOM)) {force_page_cache_readahead(mapping, filp, offset, req_size);return;}/* do read-ahead */ondemand_readahead(mapping, ra, filp, false, offset, req_size);
}

這里后續(xù)會(huì)說明這里的兩個(gè)分支到底作用為何?
不過抓這個(gè)函數(shù)的stap發(fā)現(xiàn)只能讀到1個(gè)page的請(qǐng)求,也就是do_generic_file_read只下發(fā)了1個(gè)page。

通過注釋能夠看到如果要預(yù)讀的話應(yīng)該會(huì)在ondemand_readahead函數(shù)中,結(jié)合火焰圖,這個(gè)函數(shù)預(yù)讀的話最終會(huì)走到ra_submit --> __do_page_cache_readahead 邏輯,同樣的stap抓一下這個(gè)函數(shù)的nr_to_read的參數(shù),發(fā)現(xiàn)確實(shí)預(yù)讀到了3-4個(gè)page。

定位到了函數(shù):ondemand_readahead ,預(yù)讀的多個(gè)頁面就是在這里填充的,而ra_submit只是很薄的一層調(diào)用:

unsigned long ra_submit(struct file_ra_state *ra,struct address_space *mapping, struct file *filp)
{int actual;actual = __do_page_cache_readahead(mapping, filp,ra->start, ra->size, ra->async_size);return actual;
}

到此我們結(jié)合火焰圖的調(diào)用棧知道了具體的哪個(gè)內(nèi)核函數(shù)發(fā)生了預(yù)讀,但是為什么還不清楚。

2. 問題原因

內(nèi)核預(yù)讀機(jī)制

內(nèi)核的預(yù)讀機(jī)制起源是我們還處于大多數(shù)存儲(chǔ)場景都是HDD介質(zhì),磁盤的轉(zhuǎn)動(dòng)和磁頭的尋道消耗太多的時(shí)間,而我們想要在HDD的基礎(chǔ)上提升讀性能,可以減少磁頭移動(dòng)的次數(shù),連續(xù)讀取多個(gè)扇區(qū)的數(shù)據(jù)內(nèi)容就可以。實(shí)際的操作系統(tǒng)中,用戶讀取一個(gè)文件,一般會(huì)從頭讀到尾,這一些文件在磁盤上的存儲(chǔ)都是連續(xù)的扇區(qū),也就是可以利用預(yù)讀來一次讀取多個(gè)扇區(qū),減少磁頭頻繁移動(dòng)尋道。

當(dāng)然,這個(gè)預(yù)讀機(jī)制在我們的NVME上同樣有效,現(xiàn)在大多數(shù)的nvme底層存儲(chǔ)介質(zhì)還是nand ,使用的是浮柵晶體管做存儲(chǔ)單元,通過兩極加正反電壓來控制浮柵層內(nèi)電子的移動(dòng)情況。詳細(xì)的底層nand存儲(chǔ)介質(zhì)原理介紹感興趣的同學(xué)可以參考從NMOS 和 PCM 底層存儲(chǔ)單元 來看NAND和3D XPoint的本質(zhì)區(qū)別。回到要說的預(yù)讀問題,有了預(yù)讀,可以減少一次或者多次針對(duì)nvme的IO,也就能節(jié)省幾十us-幾個(gè)ms 的時(shí)間,極大得提升了系統(tǒng)的響應(yīng)時(shí)間。

預(yù)讀(read-ahead) 算法預(yù)測即將訪問的頁面,并提前將他們讀入到page-cache中,后續(xù)的讀取就不需要產(chǎn)生io了。

主要任務(wù):

  1. 批量:把小I/O 聚集為大I/O,改善磁盤利用率,提升系統(tǒng)吞吐
  2. 提前:對(duì)應(yīng)用程序隱藏磁盤的延遲,加快系統(tǒng)響應(yīng)時(shí)間
  3. 預(yù)測:屬于預(yù)讀算法的核心任務(wù)。前兩個(gè)功能都依賴準(zhǔn)確的預(yù)測能力。包括linux , freeBSD, solaris 等主流操作系統(tǒng)都遵循一個(gè)原則:預(yù)讀僅針對(duì)順序讀模式。這個(gè)模式比較簡單且普遍,提升效果也更明顯,但是隨機(jī)讀模式對(duì)于內(nèi)核來說也是難以預(yù)測的。

觸發(fā)預(yù)讀 的條件:

  1. 內(nèi)核處理用戶進(jìn)程讀請(qǐng)求時(shí)調(diào)用:page_cache_sync_readaheadpage_cache_async_readahead

  2. 內(nèi)核為文件內(nèi)存映射分配一個(gè)頁面時(shí),即調(diào)用 mmap

  3. 用戶進(jìn)程執(zhí)行系統(tǒng)調(diào)用 readahead

  4. 用戶進(jìn)程在打開文件之后執(zhí)行posix_fadvise系統(tǒng)調(diào)用

  5. 用戶進(jìn)程執(zhí)行madvise()系統(tǒng)調(diào)用,使用MADV_WILLNEED flag 通知內(nèi)核文件內(nèi)存映射的指定區(qū)域?qū)頃?huì)被訪問

預(yù)讀的過程 是:

預(yù)讀算法的實(shí)現(xiàn)是通過維護(hù)兩個(gè)窗口:當(dāng)前窗口(current window) 和 前進(jìn)窗口(ahead window)

用戶進(jìn)程當(dāng)前訪問的page 都會(huì)在current window中,當(dāng)內(nèi)核判讀用戶進(jìn)程是順序訪問初始訪問頁面是在當(dāng)前窗口時(shí)就檢查前進(jìn)窗口是否建立,如果未建立,則建立一個(gè)新的前進(jìn)窗口,并為對(duì)應(yīng)的文件頁面觸發(fā)讀操作。如果用戶進(jìn)程的讀命中了前進(jìn)窗口的頁面,則將前進(jìn)窗口切換為當(dāng)前窗口。

如上圖,用戶訪問當(dāng)前窗口的時(shí)候會(huì)構(gòu)建前進(jìn)窗口,理想情況下當(dāng)前窗口的頁面都是已經(jīng)被cache住的,而前進(jìn)窗口則還在調(diào)度頁面到cache;當(dāng)然也會(huì)有正在訪問的當(dāng)前窗口的頁面正在調(diào)度的情況。

如果用戶進(jìn)程訪問的頁面命中了前進(jìn)窗口,則前進(jìn)窗口會(huì)切換為當(dāng)前窗口,實(shí)際的前進(jìn)窗口的大小會(huì)根據(jù)命中情況動(dòng)態(tài)調(diào)整,命中到前進(jìn)窗口的page越多,下次創(chuàng)建的前進(jìn)窗口的大小則會(huì)更大一些,否則就會(huì)縮小。

page_cache_sync_readahead

通過前面的問題分析過程,我們知道了在page_cache_sync_readahead的內(nèi)部調(diào)用中發(fā)生了預(yù)讀,用戶下發(fā)的是一個(gè)頁面,在它內(nèi)部卻讀了超過3個(gè)頁面。

看一下這個(gè)函數(shù)的邏輯,參數(shù)含義如下:

  1. mapping: 文件擁有者的address_space對(duì)象
  2. ra: 包含此頁面的文件file_ra_state描述符,持有是否進(jìn)行預(yù)讀的標(biāo)記
  3. filp: 文件對(duì)象
  4. offset: 頁面在文件中的起始偏移量
  5. req_size: 完成當(dāng)前讀操作需要的頁面數(shù)

這個(gè)函數(shù)一般會(huì)在cache-miss的時(shí)候被調(diào)用,即它的調(diào)用者發(fā)現(xiàn)文件page不在cache中,觸發(fā)這個(gè)函數(shù)去讀對(duì)應(yīng)的page,當(dāng)然也包括了預(yù)讀,因?yàn)榍懊嫖覀兺ㄟ^systemtap抓這個(gè)函數(shù)的時(shí)候也只是下發(fā)了一個(gè)page,最后它內(nèi)部的經(jīng)過ondemand_readahead的處理返回了3個(gè)page。

void page_cache_sync_readahead(struct address_space *mapping,struct file_ra_state *ra, struct file *filp,pgoff_t offset, unsigned long req_size)
{/* no read-ahead */// 如果前面填充的readahead-pages是空的話直接返回if (!ra->ra_pages)return;/* be dumb */// 這里 FMODE_RANDOM 是由posix_advise指定的隨機(jī)讀標(biāo)記,不需要預(yù)讀if (filp && (filp->f_mode & FMODE_RANDOM)) {force_page_cache_readahead(mapping, filp, offset, req_size);return;}/* do read-ahead */// 真正執(zhí)行預(yù)讀的邏輯。ondemand_readahead(mapping, ra, filp, false, offset, req_size);
}

可以看到,第二個(gè)分支中 會(huì)判斷文件mode是否為FMODE_RANDOM ,如果是的話就不執(zhí)行預(yù)讀了,僅僅讀當(dāng)前用戶進(jìn)程需要讀的page。這個(gè)標(biāo)記可以由用戶進(jìn)程打開文件的時(shí)候通過posix_advise來指定。

指定的邏輯在posix_advise系統(tǒng)調(diào)用的實(shí)現(xiàn)中:

SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice) {...case POSIX_FADV_RANDOM:spin_lock(&f.file->f_lock);f.file->f_mode |= FMODE_RANDOM;spin_unlock(&f.file->f_lock);break;...
}

回到我們要討論的預(yù)讀邏輯中,接下來看一下真正執(zhí)行預(yù)讀的函數(shù)ondemand_readahead

ondemand_readahead

這個(gè)函數(shù)主要是根據(jù)傳入的file_ra_state描述符執(zhí)行一些動(dòng)作,函數(shù)參數(shù)還是剛才page_cache_sync_readahead函數(shù)傳入進(jìn)來的。

主體邏輯是

  1. 首先判斷讀取是否從文件開頭開始,如果是,則初始化預(yù)讀信息。默認(rèn)設(shè)置的是4個(gè)page
  2. 如果不是文件頭,則判斷是否是順序訪問(連續(xù)讀),如果是,則擴(kuò)大預(yù)讀數(shù)量,一般是上次預(yù)讀數(shù)量x2
  3. 如果不是順序訪問, 則認(rèn)為是隨機(jī)讀,不適合預(yù)讀,只會(huì)讀取sys_read請(qǐng)求的page數(shù)量。
  4. 最后調(diào)用ra_submit 提交讀請(qǐng)求
static unsigned long
ondemand_readahead(struct address_space *mapping,struct file_ra_state *ra, struct file *filp,bool hit_readahead_marker, pgoff_t offset,unsigned long req_size)
{unsigned long max = max_sane_readahead(ra->ra_pages);/** start of file*/// 判斷是否是從文件開頭讀取,offset=0// 如果是,則會(huì)調(diào)用get_init_ra_size 初始化預(yù)讀頁面if (!offset)goto initial_readahead;/** It's the expected callback offset, assume sequential access.* Ramp up sizes, and push forward the readahead window.*/// 如果不是從文件開始預(yù)讀,且是順序讀(發(fā)現(xiàn)當(dāng)前的偏移地址是上次讀的起始地址+size)// 通過get_next_ra_size 擴(kuò)大預(yù)讀窗口if ((offset == (ra->start + ra->size - ra->async_size) ||offset == (ra->start + ra->size))) {ra->start += ra->size;ra->size = get_next_ra_size(ra, max);ra->async_size = ra->size;goto readit; // 進(jìn)入ra_submit執(zhí)行實(shí)際的預(yù)讀}/** Hit a marked page without valid readahead state.* E.g. interleaved reads.* Query the pagecache for async_size, which normally equals to* readahead size. Ramp it up and use it as the new readahead size.*/// 發(fā)現(xiàn)當(dāng)前文件被打上了一個(gè)預(yù)讀失效的標(biāo)記,這里默認(rèn)傳入的是falseif (hit_readahead_marker) {pgoff_t start;rcu_read_lock();start = radix_tree_next_hole(&mapping->page_tree, offset+1,max);rcu_read_unlock();if (!start || start - offset > max)return 0;ra->start = start;ra->size = start - offset;	/* old async_size */ra->size += req_size;ra->size = get_next_ra_size(ra, max);ra->async_size = ra->size;goto readit;}/** oversize read*/// 大塊預(yù)讀,即sys_read請(qǐng)求的頁面大小超過了最大的預(yù)讀設(shè)置// 重新初始化預(yù)讀窗口,預(yù)讀更多的頁面if (req_size > max)goto initial_readahead;/** sequential cache miss*/// 內(nèi)核重新發(fā)現(xiàn)當(dāng)前讀是順序讀,創(chuàng)建新的當(dāng)前窗口if (offset - (ra->prev_pos >> PAGE_CACHE_SHIFT) <= 1UL)goto initial_readahead;/** Query the page cache and look for the traces(cached history pages)* that a sequential stream would leave behind.*/// 這個(gè)函數(shù)里面發(fā)現(xiàn)不是順序讀,會(huì)返回0,直接不進(jìn)行預(yù)讀了// 后續(xù)的__do_page_cache_readahead 函數(shù)readahead size被設(shè)置為0 了if (try_context_readahead(mapping, ra, offset, req_size, max))goto readit;/** standalone, small random read* Read as is, and do not pollute the readahead state.*/return __do_page_cache_readahead(mapping, filp, offset, req_size, 0);// 初始化當(dāng)前預(yù)讀窗口
initial_readahead:ra->start = offset;ra->size = get_init_ra_size(req_size, max);ra->async_size = ra->size > req_size ? ra->size - req_size : ra->size;readit:/** Will this read hit the readahead marker made by itself?* If so, trigger the readahead marker hit now, and merge* the resulted next readahead window into the current one.*/if (offset == ra->start && ra->size == ra->async_size) {ra->async_size = get_next_ra_size(ra, max);ra->size += ra->async_size;}// 實(shí)際進(jìn)行預(yù)讀指定page個(gè)數(shù)的調(diào)用return ra_submit(ra, mapping, filp);
}

3. 優(yōu)化

到這里我們就知道了操作系統(tǒng)的預(yù)讀優(yōu)化主要是針對(duì)順序讀場景,且會(huì)動(dòng)態(tài)調(diào)整預(yù)讀窗口的大小。那回到我們r(jià)ocksdb這里,業(yè)務(wù)下發(fā)的是隨機(jī)讀,但部分讀請(qǐng)求顯然是發(fā)生了預(yù)讀。因?yàn)闇y試的場景是用極少blockcache的,也就是這一些想要預(yù)讀到page-cache的datablock 大多數(shù)都不會(huì)被cache住。

那我們有沒有辦法完全不讓操作系統(tǒng)預(yù)讀呢,減少這個(gè)場景下的預(yù)讀I/O 。

回到rocksdb 讀datablock 的邏輯:

rocksdb::DBImpl::Getrocksdb::DBImpl::GetImplrocksdb::Version::Getrocksdb::TableCache::Getrocksdb::BlockBasedTable::Getrocksdb::BlockBasedTable::NewDataBlockIterator<rocksdb::DataBlockIter>rocksdb::BlockBasedTable::RetrieveBlock<rocksdb::Block>rocksdb::BlockBasedTable::MaybeReadBlockAndLoadToCache<rocksdb::Block>rocksdb::BlockFetcher::ReadBlockContentsrocksdb::RandomAccessFileReader::Read

其中在rocksdb::TableCache::Get 邏輯中需要先找到點(diǎn)查的sst文件,獲取一個(gè)文件handle

會(huì)進(jìn)入到如下邏輯:

TableCache::FindTable // 如果在 block_cache 中找不到,則會(huì)進(jìn)入如下邏輯中。本身我們設(shè)置的blockcache也很小,大多數(shù)的key都找不到TableCache::GetTableReader 

GetTableReader邏輯中主要是創(chuàng)建一個(gè)BlockBasedTable的FileReader。

Status TableCache::GetTableReader(const EnvOptions& env_options,const InternalKeyComparator& internal_comparator, const FileDescriptor& fd,bool sequential_mode, bool record_read_stats, HistogramImpl* file_read_hist,std::unique_ptr<TableReader>* table_reader,const SliceTransform* prefix_extractor, bool skip_filters, int level,bool prefetch_index_and_filter_in_cache) {std::string fname =TableFileName(ioptions_.cf_paths, fd.GetNumber(), fd.GetPathId());std::unique_ptr<RandomAccessFile> file;// 打開傳入的文件Status s = ioptions_.env->NewRandomAccessFile(fname, &file, env_options);RecordTick(ioptions_.statistics, NO_FILE_OPENS);if (s.ok()) {// posix_fadvise 設(shè)置打開文件的讀模式if (!sequential_mode && ioptions_.advise_random_on_open) {file->Hint(RandomAccessFile::RANDOM);}StopWatch sw(ioptions_.env, ioptions_.statistics, TABLE_OPEN_IO_MICROS);// 創(chuàng)建一個(gè)BlockBasedTable的table_readerstd::unique_ptr<RandomAccessFileReader> file_reader(new RandomAccessFileReader(std::move(file), fname, ioptions_.env,record_read_stats ? ioptions_.statistics : nullptr, SST_READ_MICROS,file_read_hist, ioptions_.rate_limiter, ioptions_.listeners));s = ioptions_.table_factory->NewTableReader(TableReaderOptions(ioptions_, prefix_extractor, env_options,internal_comparator, skip_filters, immortal_tables_,level, fd.largest_seqno, block_cache_tracer_),std::move(file_reader), fd.GetFileSize(), table_reader,prefetch_index_and_filter_in_cache);TEST_SYNC_POINT("TableCache::GetTableReader:0");}return s;
}

可以看到在GetTableReader的過程中會(huì)先打開文件,打開之后會(huì)根據(jù)sequential_modeioptions_.advise_random_on_open配置來設(shè)置文件的模式。這里默認(rèn)的sequential_mode傳入的時(shí)候是false,所以如果那個(gè)option是true,則會(huì)設(shè)置一個(gè)RANDOM

其底層是通過posix_fadvise來設(shè)置文件的預(yù)讀模式:

void PosixRandomAccessFile::Hint(AccessPattern pattern) {if (use_direct_io()) {return;}switch (pattern) {case NORMAL:Fadvise(fd_, 0, 0, POSIX_FADV_NORMAL);break;case RANDOM:// 對(duì)fd 下發(fā)RANDOM 標(biāo)記Fadvise(fd_, 0, 0, POSIX_FADV_RANDOM);break;case SEQUENTIAL:Fadvise(fd_, 0, 0, POSIX_FADV_SEQUENTIAL);break;case WILLNEED:Fadvise(fd_, 0, 0, POSIX_FADV_WILLNEED);break;case DONTNEED:Fadvise(fd_, 0, 0, POSIX_FADV_DONTNEED);break;default:assert(false);break;}
}int Fadvise(int fd, off_t offset, size_t len, int advice) {
#ifdef OS_LINUXreturn posix_fadvise(fd, offset, len, advice);
#else(void)fd;(void)offset;(void)len;(void)advice;return 0;  // simply do nothing.
#endif
}

到此,我們就知道了通過這里的選項(xiàng) ioptions_.advise_random_on_open = true 能夠讓posix_fadvise設(shè)置內(nèi)核的預(yù)讀建議POSIX_FADV_RANDOM,讓隨機(jī)讀場景不進(jìn)行內(nèi)核的自動(dòng)預(yù)讀。

最后,在page_cache_sync_readahead 中會(huì)進(jìn)入到不進(jìn)行預(yù)讀的邏輯中。

總結(jié)

以上是生活随笔為你收集整理的Rocksdb 通过posix_advise 让内核减少在page_cache的预读的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

欧美午夜寂寞影院 | 日韩精品aaa | 香蕉精品视频在线观看 | 国产一区二区日本 | 美女视频永久黄网站免费观看国产 | 天天射天天干天天 | av在线免费播放网站 | 亚洲激情婷婷 | 亚洲久草在线视频 | 成人sm另类专区 | 黄网站大全 | 久久韩国免费视频 | 日韩中文字幕在线看 | 综合色爱| 久久久午夜视频 | 久久久久久久久久久国产精品 | 丝袜精品视频 | 西西大胆免费视频 | 午夜久久久久久久久久久 | 99久久日韩精品视频免费在线观看 | 肉色欧美久久久久久久免费看 | 久久久伦理 | 男女靠逼app | 久久久久久久久毛片精品 | 久久精品美女视频 | 91看片在线 | 久久草精品| 国产日韩在线播放 | 在线免费观看视频你懂的 | 国产剧情av在线播放 | 欧美一级性生活片 | 亚洲欧美乱综合图片区小说区 | 狠狠躁日日躁夜夜躁av | 亚洲黄a | 人人插人人 | 国产69精品久久99不卡的观看体验 | 成人黄色av免费在线观看 | 精品国产诱惑 | 亚州av免费 | 婷婷丁香激情综合 | 啪啪精品 | 成人午夜精品久久久久久久3d | 97在线视频免费观看 | 91色在线观看视频 | 国产精品美女999 | 一级特黄av| 中文字幕av在线 | 玖玖精品视频 | 97视频在线观看成人 | 免费看一级特黄a大片 | 91桃色免费观看 | 欧美激情视频在线观看免费 | 国语黄色片 | 黄色亚洲免费 | sm免费xx网站 | 五月天精品视频 | 久久99婷婷 | 在线观看黄色小视频 | 久久精品之 | 亚洲人成精品久久久久 | 久久国产系列 | 亚州精品天堂中文字幕 | 国产精品视频资源 | 欧美性视频网站 | 一区二区三区四区五区六区 | 久久香蕉影视 | 国产美女搞久久 | 免费看精品久久片 | 日本动漫做毛片一区二区 | 欧美国产精品一区二区 | 国色天香永久免费 | 国产91精品一区二区 | 色狠狠综合天天综合综合 | 亚洲国产美女久久久久 | 久久综合干 | 夜夜视频| 婷婷激情久久 | 国产日产精品一区二区三区四区 | 黄色av电影在线 | 免费高清在线视频一区· | 日韩啪啪小视频 | 久久久久欠精品国产毛片国产毛生 | 日日干夜夜爱 | 午夜12点| 中文字幕在线播放av | 国产精品美女毛片真酒店 | 天天久久综合 | 二区三区在线观看 | 六月丁香久久 | 精品久久久久_ | 国产精品网址在线观看 | 99免费在线播放99久久免费 | 日韩乱色精品一区二区 | 日本在线观看中文字幕无线观看 | www日韩精品| 成 人 黄 色 视频播放1 | 成人a免费视频 | 久久影院亚洲 | 久久久91精品国产一区二区三区 | 99久久er热在这里只有精品15 | 久久这里只有精品首页 | 在线观看中文字幕第一页 | 黄色av一区二区 | 中文字幕日本电影 | 国产精品第10页 | 久久99免费观看 | 网站免费黄 | 丁香花中文在线免费观看 | 精品免费一区二区三区 | 午夜的福利| 99精品视频免费全部在线 | 免费看国产黄色 | 国产亚洲精品日韩在线tv黄 | 毛片无卡免费无播放器 | 国产成人在线免费观看 | 久草视频99 | 色综合天天在线 | 麻豆视频在线 | 成人av电影免费在线播放 | 精品人人人 | 六月丁香激情综合色啪小说 | 免费黄色a级毛片 | 蜜臀aⅴ国产精品久久久国产 | 日本不卡123 | 免费a v视频 | 91手机电影 | 免费看的视频 | 夜夜爽夜夜操 | 91精品久久久久久 | 亚洲精品乱码久久久久久蜜桃91 | 午夜精品久久久久久久99 | 五月激情久久久 | 中文字幕在线网址 | 日韩欧美在线国产 | 久久人人97超碰com | 日韩黄在线观看 | 区一区二区三区中文字幕 | av韩国在线 | 五月婷婷导航 | 九九九九九国产 | 欧美黄在线 | 欧美久久久久久久久久久久久 | 成人免费视频网站在线观看 | 亚洲va在线va天堂 | 偷拍区另类综合在线 | 日日干网 | 国产在线观看免费观看 | 91亚洲综合 | 天天爱天天爽 | 国产男女无遮挡猛进猛出在线观看 | 91av在| 麻豆精品视频 | 81精品国产乱码久久久久久 | 在线观看日本高清mv视频 | 三级黄色欧美 | 久久永久视频 | 操操日 | 黄色片网站av | 天天爽天天搞 | 久久视频中文字幕 | 在线一区av | 在线观看91av | 成人va视频 | 成人欧美日韩国产 | 日韩特黄一级欧美毛片特黄 | 久久久久久美女 | 欧美日韩视频免费 | 久久99操 | 一级免费看 | 亚洲精品三级 | 天天看天天干天天操 | 国产成人在线综合 | 久草视频在线看 | 西西44人体做爰大胆视频 | 国产又粗又猛又黄视频 | 91精品国产综合久久福利 | 久草91视频 | 日本三级大片 | 国产精品国产三级国产不产一地 | 欧美日韩91 | 99九九免费视频 | 国产午夜三级一区二区三桃花影视 | 中文字幕国语官网在线视频 | 免费看污在线观看 | 日韩成人不卡 | 狠狠狠狠狠狠天天爱 | 五月花婷婷 | 亚洲欧美激情精品一区二区 | 天天干夜夜操视频 | 国产区欧美 | 亚洲在线网址 | 国产高清免费视频 | 91av在线免费视频 | 中日韩男男gay无套 日韩精品一区二区三区高清免费 | av福利电影 | 色吊丝在线永久观看最新版本 | 国产一级免费播放 | 黄色av播放 | 国内精品久久久久久久久久久 | av成人动漫在线观看 | 青春草免费在线视频 | 六月天色婷婷 | 精品国产一区二区三区免费 | 一本一本久久a久久 | 国产理论片在线观看 | 久久成 | 亚洲欧美视频在线观看 | 少妇搡bbbb搡bbb搡忠贞 | 日韩美精品视频 | 色婷婷视频| 亚洲天堂视频在线 | 99re国产 | 日韩精品免费一线在线观看 | 91在线看黄 | 亚洲蜜桃在线 | 六月色 | 天天操天天吃 | 日韩欧美精品在线观看 | 日韩三级中文字幕 | 香蕉影院在线播放 | 色婷婷激情 | 911香蕉| 久久久九色精品国产一区二区三区 | 91激情在线视频 | 国产黄色片免费在线观看 | 在线黄色av电影 | 国产黄色片久久 | 91免费高清在线观看 | 国产精品短视频 | 人人插人人草 | 久产久精国产品 | 国产欧美在线一区 | 免费特级黄毛片 | 国内精品中文字幕 | 久久网页 | 久久不卡免费视频 | 91视频观看免费 | 欧美福利视频 | 91探花在线 | 国产一级在线观看 | 97超碰中文字幕 | 成年人黄色大片在线 | 亚洲,播放 | 99热99re6国产在线播放 | 国产99久久久国产精品成人免费 | 国产不卡高清 | 天天综合色天天综合 | 国产精品视频在线看 | 99免费在线视频观看 | 夜夜操综合网 | 久久精品高清视频 | 最新中文字幕视频 | 久久韩国免费视频 | 日韩高清一区 | 久久免费视频在线观看6 | 久草视频在线看 | 九九视频免费在线观看 | 国产在线精 | 91在线观看视频网站 | av一级网站| 一级理论片在线观看 | 日韩特级毛片 | 久久久久国产一区二区三区 | 欧美日韩久久不卡 | 2020天天干天天操 | 黄色小说视频网站 | 97人人超| 精品一区在线 | 在线观看黄网 | 婷婷精品国产欧美精品亚洲人人爽 | 亚洲日本va午夜在线电影 | 91精品国产麻豆 | 国产精品美女久久久免费 | 国产色拍拍拍拍在线精品 | 欧美在线不卡一区 | 91精品视频免费在线观看 | 久久成人在线视频 | 日本亚洲国产 | 天天天插 | 欧美成人高清 | 欧美一区二区精品在线 | 麻豆视频入口 | 高清免费在线视频 | 在线观看一级视频 | 狠狠干在线 | 伊人天堂网 | 综合色亚洲 | 欧美日韩一区二区在线 | 日本中文字幕在线免费观看 | 亚洲日本在线视频观看 | 国产黄在线播放 | 精品国产一区二区三区av性色 | 一级α片 | 精产嫩模国品一二三区 | 国产免费一区二区三区网站免费 | 久久激情视频 久久 | 天天爽夜夜爽人人爽曰av | av韩国在线 | 日本精品在线 | 在线观看黄色的网站 | 国产色啪 | 日日操日日干 | 成人在线视频论坛 | 久久精品中文字幕一区二区三区 | 日日干 天天干 | 国产亚洲一区二区三区 | 色婷婷精品 | 在线之家免费在线观看电影 | 91精品成人| 国产精品久久久久三级 | 欧美精品v国产精品 | 中文字幕av播放 | 国产午夜精品福利视频 | 97人人超碰在线 | 午夜在线观看 | 免费一级片视频 | 激情影院在线观看 | 黄色成人影院 | 91精品国产91久久久久福利 | 欧美精品九九99久久 | 国产999精品久久久久久绿帽 | 日韩h在线观看 | 久久免费视频在线观看6 | 精品视频在线观看 | 岛国精品一区二区 | 中文字幕日韩有码 | 成人中心免费视频 | 播五月综合 | 久久有精品 | 四虎影视精品永久在线观看 | 在线综合 亚洲 欧美在线视频 | 国产精品久久久久永久免费观看 | av一本久道久久波多野结衣 | 亚洲永久精品一区 | 日本久久中文字幕 | 免费十分钟 | 久久躁日日躁aaaaxxxx | 91探花在线 | 国产理伦在线 | 99免费在线播放99久久免费 | 国产四虎在线 | 国产91免费在线 | 日韩r级在线 | 亚洲国产三级 | 中文字幕在线观看的网站 | 国产一级黄色av | 国产精品一区二区av | 美女黄视频免费看 | 欧美在线你懂的 | 91亚洲精| 九九热中文字幕 | 免费视频xnxx com| 最近最新中文字幕视频 | 国产色久 | 精品亚洲一区二区三区 | 91精品国产一区二区在线观看 | 一级黄色a视频 | 日韩亚洲精品电影 | av在线不卡观看 | 久久久久久久久久免费 | 天天干.com| 一级片视频免费观看 | 91久久国产自产拍夜夜嗨 | 日本久久精品 | 超碰人人超碰 | 日本最新中文字幕 | 国产精品网红直播 | 97电影在线观看 | 欧美日韩免费观看一区=区三区 | 激情欧美一区二区三区 | 蜜桃视频日韩 | 免费色视频网站 | 国产在线观看午夜 | 欧美日韩一区二区三区免费视频 | 91探花国产综合在线精品 | 国产精品6 | 精品国产乱码久久久久久三级人 | 亚洲伦理一区二区 | 四虎永久网站 | 992tv在线观看网站 | 天天躁天天躁天天躁婷 | 日本性xxxxx| 在线精品视频免费播放 | 美女国产精品 | 天天看天天干天天操 | 国产中出在线观看 | 日本电影黄色 | 一区二区中文字幕在线播放 | 综合色在线观看 | 五月丁色 | 国产91在线免费视频 | 日本久久久久久久久久久 | 91麻豆精品国产91久久久使用方法 | 日本在线成人 | 天天色图 | av资源中文字幕 | 午夜精品视频免费在线观看 | 天天操比 | 国产精品一区二区精品视频免费看 | 99久久激情 | 久久久免费电影 | 亚洲欧美日韩在线一区二区 | a级片在线播放 | 国产在线2020 | 奇米网8888 | 在线a人片免费观看视频 | 综合久久影院 | 国内精品久久久久国产 | 中文字幕在线播放第一页 | 亚洲午夜精品久久久 | 色国产视频 | 三级黄色免费 | 精品毛片久久久久久 | 日本三级久久久 | 亚洲久草视频 | 国产高清第一页 | 99超碰在线观看 | 亚洲美女视频网 | 久久久免费少妇 | 五月网婷婷 | 日韩午夜精品 | 国产一级黄色电影 | 亚洲在线观看av | 天天操天天干天天爱 | 亚洲激情在线播放 | 视频二区 | 美女福利视频 | 激情网站网址 | 91免费观看国产 | 亚洲激情一区二区三区 | 日韩高清在线一区二区 | 日韩黄色中文字幕 | 久久国产精品久久w女人spa | 久久精品视频一 | 九九热精品国产 | 久久国产品 | 欧美日韩在线视频一区二区 | 婷婷视频导航 | 97色免费视频 | 一级成人免费视频 | 日韩久久精品一区二区三区下载 | 日韩美在线观看 | 免费看的黄色 | 日韩专区在线观看 | 91视频免费看片 | 亚洲精品456在线播放 | 91新人在线观看 | 99精品免费网| 开心激情久久 | 天天干天天射天天插 | 久久黄网站 | 亚洲精品啊啊啊 | 不卡中文字幕av | 国产精品2018 | 亚洲视频2| 国产免费观看av | 日日添夜夜添 | 九九在线精品视频 | 高清国产一区 | 日韩中文字幕在线不卡 | 色婷婷激情 | 国产一级a毛片视频爆浆 | 亚洲精品一区二区18漫画 | 人人草在线视频 | 91视频在线免费下载 | 国产精品视频99 | 婷婷精品国产欧美精品亚洲人人爽 | 国产精品99久久久久久小说 | 日日夜夜精品免费观看 | 精品日本视频 | 香蕉影院在线播放 | 精品麻豆入口免费 | www.五月婷婷.com | 区一区二区三区中文字幕 | 亚洲va在线va天堂va偷拍 | 亚洲精品88欧美一区二区 | 日韩激情av在线 | 久久综合久久综合久久 | 日韩av中文字幕在线 | 在线中文字幕电影 | 香蕉视频导航 | 91看片在线观看 | av大片网址 | 大型av综合网站 | 久久成人国产精品免费软件 | av超碰在线| 国产精选在线观看 | 91久久国产自产拍夜夜嗨 | 久久中文精品视频 | 久久精品99久久久久久2456 | 日本爱爱免费视频 | 国产美女视频免费观看的网站 | 99 色 | 精品视频免费久久久看 | 综合久久久| 国产又粗又硬又爽视频 | 免费特级黄色片 | av在线免费播放网站 | 中文字幕丝袜制服 | 亚洲第一区在线观看 | 久久久久一区二区三区四区 | 亚洲免费一级 | 九九热av | av电影在线观看完整版一区二区 | 人人狠狠综合久久亚洲 | 亚洲男人天堂2018 | 亚洲最大的av网站 | 精品色999 | 欧美a在线免费观看 | 国色天香av | 国产精品大尺度 | 激情伊人 | 97国产人人 | 99色视频在线 | 天天色天天射天天操 | av网在线观看 | 免费视频a | 亚洲欧美视频 | 国产黄色一级大片 | 亚洲午夜电影网 | 日韩av高潮 | 成人国产精品一区 | 黄色福利网站 | 日韩视频精品在线 | 国产 视频 高清 免费 | 久久国产成人午夜av影院宅 | 欧美精彩视频在线观看 | 亚洲精品视频免费观看 | 天堂av观看 | 婷婷色av | 成人黄色免费观看 | 开心色插 | 欧美日韩三区二区 | 亚洲精欧美一区二区精品 | 日韩狠狠操 | 久久精品理论 | 黄色小视频在线观看免费 | 日本夜夜草视频网站 | 在线国产高清 | 久久久精品欧美一区二区免费 | 国产精品第一页在线观看 | 久久视频免费在线 | 精品福利av | 久久国产香蕉视频 | 国产一区欧美一区 | 色偷偷88欧美精品久久久 | 久久综合精品国产一区二区三区 | 亚洲精品在线一区二区 | 久久综合狠狠狠色97 | 免费在线看成人av | 最近中文国产在线视频 | 91丨九色丨高潮丰满 | 日韩av免费在线电影 | 久久天天躁夜夜躁狠狠85麻豆 | 婷婷丁香六月 | 黄色软件在线看 | 一区二区亚洲精品 | 国产精品video | 国产成人一区二区三区影院在线 | 999电影免费在线观看 | 日韩久久久久久久久久久久 | 亚洲一区黄色 | 国产免费观看久久黄 | 色在线最新 | 国产资源在线免费观看 | 色www.| 伊人天堂久久 | 九九综合在线 | 国产网红在线 | 涩涩网站在线播放 | av电影中文字幕在线观看 | 六月丁香婷婷网 | 精品在线你懂的 | 国产精品国产自产拍高清av | 2021国产精品视频 | 在线观看中文 | 成人av一区二区兰花在线播放 | 96国产精品视频 | 狠狠88综合久久久久综合网 | a黄在线观看 | 人人干人人模 | 手机在线小视频 | 久久欧洲视频 | 成人午夜电影在线观看 | 国产精品尤物视频 | 欧美色图88 | 狠狠伊人 | 激情久久一区二区三区 | 日韩精品一区二区三区丰满 | 一本色道久久精品 | 国产中年夫妇高潮精品视频 | 日韩网 | 久久一区二区免费视频 | 成人国产精品久久久春色 | 中文字幕精品三区 | 在线免费观看黄色大片 | 99热国产在线中文 | 色噜噜在线观看 | 91精品在线观看入口 | 在线涩涩 | 国产精品精品国产婷婷这里av | 深夜免费福利网站 | 福利精品在线 | 久草视频资源 | 色小说av | 国产成人av在线影院 | 日韩艹| 欧美精品九九99久久 | 日日夜夜天天久久 | 亚洲午夜精品久久久久久久久久久久 | 久久人人爽人人爽人人片av软件 | 超碰在线观看av.com | 中文字幕中文字幕中文字幕 | 精品久久久久国产免费第一页 | 天天综合网在线 | 国语久久 | 国产精品美女久久久网av | 欧美日韩免费观看一区二区三区 | 久久久久在线 | 亚洲福利精品 | 久久国产精品二国产精品中国洋人 | av看片网 | 在线亚洲播放 | 亚洲精品小区久久久久久 | 亚洲黄色一级电影 | 亚洲婷婷综合色高清在线 | 91免费观看视频在线 | 国产一区视频在线 | 狠狠干网站 | 久久久免费播放 | 久久久久久久久久久久国产精品 | 国产麻豆精品传媒av国产下载 | 丁香电影小说免费视频观看 | 婷婷激情综合网 | 夜夜操天天干 | 国产黄色看片 | 精品国产一区二区三区四区在线观看 | 久久久久国产成人精品亚洲午夜 | 中文字幕在线国产精品 | 国产资源中文字幕 | 国产伦理久久精品久久久久_ | 国产在线 一区二区三区 | 96久久欧美麻豆网站 | 一区二区 不卡 | www..com黄色片 | 午夜精品久久久久久久99无限制 | 国产美女精品视频免费观看 | 亚洲免费观看视频 | 免费观看版 | 91精品视频免费在线观看 | 操一草| 国产精品成人一区二区 | 成人欧美在线 | 久久国产视屏 | 六月色丁香| 久久久午夜电影 | 欧美 国产 视频 | 国产黄色大片 | 久久国产精品久久精品国产演员表 | 成人黄色在线 | 91传媒在线看| 免费视频你懂得 | www.在线看片.com | 久久久久亚洲精品中文字幕 | 五月在线视频 | 精品一二三区视频 | 中文字幕 欧美性 | www.色午夜.com | 97电影网站 | 深爱激情婷婷网 | 美女免费电影 | 色国产视频 | 亚洲成av人片在线观看香蕉 | 亚洲成人国产精品 | 久久精品成人热国产成 | 精品一区二区在线免费观看 | 麻豆视频国产精品 | 国产69久久 | 精品视频www | 在线va网站| 国产福利在线 | 日韩在线视频观看 | 中文在线资源 | 亚洲一级黄色 | 在线电影 一区 | 久久久久免费观看 | 天天色天天上天天操 | 激情www| 成人免费看黄 | 99久久精品国产免费看不卡 | 精品国产一区二区三区在线 | 欧美一级电影 | 久草视频在线资源站 | av在观看| 欧美 亚洲 另类 激情 另类 | 97伊人网 | 久久久伦理 | 99亚洲国产 | 国产中文字幕久久 | 最新av电影网址 | 成人中心免费视频 | www国产一区| 黄色免费观看网址 | 97综合视频 | 干综合网 | 精品国产亚洲日本 | 在线成人看片 | 在线免费国产视频 | 日韩在线视频播放 | 激情综合色播五月 | 99视频在线观看一区三区 | 日韩欧美在线一区二区 | 成人a视频 | 亚洲九九九在线观看 | a视频在线观看 | 亚洲成人国产精品 | 日日爽日日操 | 国产在线精品区 | 久久在线免费观看视频 | 91九色pron| 日韩精品一区不卡 | 亚洲三级视频 | 色资源二区在线视频 | 婷婷六月天丁香 | 日日久视频 | 日韩不卡高清视频 | 在线视频电影 | 欧洲性视频 | 91av视频在线免费观看 | 国产麻豆果冻传媒在线观看 | 亚洲成av人片 | 99爱这里只有精品 | 夜夜躁狠狠躁日日躁 | 色五婷婷 | 婷婷色网址 | 天天在线操 | 伊人五月天.com | 97精品视频在线 | 欧美精品免费在线 | 一本之道乱码区 | 香蕉视频在线看 | 国产精品美女在线观看 | 天天操夜夜逼 | 操久| 亚洲精品乱码久久久久v最新版 | 国产精品久久久久久久久久久久午 | 亚洲欧美成人综合 | 欧美高清成人 | 99久久99久久免费精品蜜臀 | 免费在线观看毛片网站 | 一二三区高清 | 在线播放91 | 亚洲综合激情 | 视频国产在线 | 91精品视频一区二区三区 | 色橹橹欧美在线观看视频高清 | 免费日韩一区 | 日韩在线字幕 | 人人玩人人添人人澡97 | 国产色啪| 五月的婷婷| 97超碰在| 成人蜜桃 | 精品国产免费一区二区三区五区 | 日日碰狠狠躁久久躁综合网 | 国产区在线 | 久久视频热 | 日韩精品视频网站 | 狠狠干在线播放 | 午夜精品一区二区三区在线 | 四虎最新域名 | 狠狠操综合 | www免费黄色 | 久久久影院一区二区三区 | 91免费视频国产 | 欧美久久久一区二区三区 | 欧洲视频一区 | 欧美日韩不卡一区二区三区 | 天天操人人干 | 色婷婷av在线 | 国产午夜精品久久久久久久久久 | 国产精品美女久久久久久 | 国产精品网红福利 | 国产永久免费观看 | 国产亚洲精品福利 | 久久视影 | 亚洲播播 | 午夜视频在线观看网站 | 久精品视频免费观看2 | 天堂网在线视频 | 国产h在线播放 | 蜜臀久久99精品久久久久久网站 | 麻豆国产露脸在线观看 | 欧美日韩精品在线播放 | 色综合久久中文综合久久牛 | 四虎影视4hu4虎成人 | 日韩极品视频在线观看 | 97福利社 | 国产美女免费观看 | 久久视频一区二区 | 91大神精品视频在线观看 | avav99| 成人sm另类专区 | 超碰夜夜 | 婷婷六月丁 | 婷婷丁香导航 | 久久综合狠狠综合久久激情 | 特级黄色视频毛片 | 久久黄色影院 | 婷婷久久网 | 成人午夜电影网站 | 69绿帽绿奴3pvideos | 日韩视频一区二区在线观看 | 99精品国产在热久久 | 久久久精品福利视频 | 成人黄色电影视频 | 久草在线官网 | 免费看污在线观看 | 亚洲国产视频在线 | 国产精品va在线观看入 | 国产一区二区观看 | 久久综合在线 | 国产日韩中文字幕在线 | 啪啪肉肉污av国网站 | 国产欧美久久久精品影院 | 久久国产精品久久w女人spa | 欧美日韩精品综合 | 在线观看视频色 | 波多野结衣电影一区二区三区 | 在线免费观看麻豆视频 | 国产 中文 日韩 欧美 | 国产自在线 | 亚洲资源网 | 99精品乱码国产在线观看 | 免费合欢视频成人app | 右手影院亚洲欧美 | 成人在线小视频 | 亚洲国产精品一区二区久久,亚洲午夜 | 在线av资源 | 视频在线99 | 91久久人澡人人添人人爽欧美 | 国产黄色精品在线观看 | 日批视频在线播放 | 日本精品视频在线观看 | 夜夜嗨av色一区二区不卡 | 国产精品麻豆视频 | 天天操天天射天天添 | 久久久精品一区二区 | 成人在线视频论坛 | 日韩www在线 | 99亚洲国产| 婷婷色网 | 91av播放| 一区精品久久 | 欧美日韩18 | 欧美日韩在线视频一区二区 | 欧美粗又大 | 久久视频这里有久久精品视频11 | 国产人成免费视频 | 国产精品视频地址 | 国产精品1区2区在线观看 | 91最新网址在线观看 | 国产黄色在线网站 | 91porny九色91啦中文 | 国产高清av| 99这里只有精品视频 | 97视频网址| 国产亚洲一级高清 | 欧美男女爱爱视频 | 99精品视频免费 | 天天干 天天摸 天天操 | 国产精品99久久免费黑人 | 日韩久久片| av观看网站 | 欧美美女视频在线观看 | 日本在线视频网址 | 日韩免费一区二区在线观看 | 在线中文字幕一区二区 | 色婷婷狠狠 | 天天综合网天天综合色 | 日本 在线 视频 中文 有码 | 成人精品久久久 | 日韩一二三| 色噜噜狠狠色综合中国 | 精品久久久久久亚洲综合网 | 亚洲精品国偷自产在线91正片 | 日韩免费一区二区 | 国产高清第一页 | 91chinese在线| 日韩免费观看高清 | 亚洲国产经典视频 | 国产综合小视频 | 999久久a精品合区久久久 | 精品国产亚洲一区二区麻豆 | 亚洲开心激情 | 精品免费在线视频 | 九九综合九九 | 国产精品久久久免费看 | 日韩在线观看一区 | 国产精品久久一区二区无卡 | 色综合久久精品 | 又黄又爽又刺激视频 | 国产999精品久久久影片官网 | 日日夜夜精品视频 | 色综合咪咪久久网 | 国产精品青草综合久久久久99 | 97国产大学生情侣白嫩酒店 | 亚洲欧洲国产精品 | 新av在线| 五月天激情视频 | 亚洲男模gay裸体gay | 久久99婷婷| 在线日韩亚洲 | 久草在线综合 | av片在线看 | 久草网站 | 国产一区二区三区免费视频 | 成人三级网址 | 黄网站免费看 | 日韩精品视频久久 | 天天色综合天天 | www.亚洲黄| 日韩欧美99 | 亚洲黄色av网址 | 91中文字幕在线播放 | 久久综合精品国产一区二区三区 | 免费在线h| 五月婷婷综合网 | 日韩高清免费在线观看 | 亚洲在线视频观看 | 欧美国产精品久久久久久免费 | 国产精品女同一区二区三区久久夜 | 国产黑丝一区二区三区 | 五月婷婷色播 | 日韩精选在线观看 | 丁香av在线 | 中文字幕国语官网在线视频 | 国产美腿白丝袜足在线av | 国产色婷婷 | 色婷婷 亚洲 | 永久免费av在线播放 | 中文字幕91在线 | 日韩精品久久久久久 | 亚洲乱码国产乱码精品天美传媒 | 狠狠色网 | 色偷偷88888欧美精品久久久 | 最新av网址在线 | 国产视频精选 | 久久久久久久久免费视频 | 婷婷播播网 | 人人爽人人香蕉 | 五月婷婷一级片 | 亚洲精品激情 | 亚洲国产片色 | 日韩精品91偷拍在线观看 | 成人综合婷婷国产精品久久免费 | 欧美福利片在线观看 | 午夜精品一二三区 | 色亚洲激情 | 久草在线在线精品观看 | 国产精品入口麻豆www | a视频在线播放 | 欧美一区日韩精品 | 久久久91精品国产一区二区三区 | 成人在线播放av | 91看片在线观看 | 欧美一级在线观看视频 | 特黄一级毛片 | 日韩欧美一区二区在线 | 99久久婷婷国产 | 日日爱夜夜爱 | 久久国产影院 | 欧美污污视频 | 成人午夜网 | 亚洲男女精品 | 久久久免费播放 | av在线网站免费观看 | 国产福利免费在线观看 | 毛片网站观看 | 国产精国产精品 | 黄色小网站在线 | 成人a视频在线观看 | 国产精品免费久久久 | 午夜久草 | 99色亚洲 | 国内精品在线看 | 日本少妇视频 | 五月婷婷六月丁香 | 久草| 中文字幕 第二区 | 日韩亚洲国产中文字幕 | 六月丁香色婷婷 | 成片人卡1卡2卡3手机免费看 | 成人在线视频免费 | 成年人视频在线观看免费 | 精品国产乱码久久久久久1区2匹 | 久久久久99精品国产片 | 亚洲精品2区 |