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

字節跳動百萬級Metrics Agent性能優化的探索與實踐

開發
本文將介紹我們在Agent性能優化上的探索和實踐。

背景

圖片圖片

metricserver2 (以下簡稱Agent)是與字節內場時序數據庫 ByteTSD 配套使用的用戶指標打點 Agent,用于在物理機粒度收集用戶的指標打點數據,在字節內幾乎所有的服務節點上均有部署集成,裝機量達到百萬以上。此外Agent需要負責打點數據的解析、聚合、壓縮、協議轉換和發送,屬于CPU和Mem密集的服務。兩者結合,使得Agent在監控全鏈路服務成本中占比達到70%以上,對Agent進行性能優化,降本增效是刻不容緩的命題。

基本架構

圖片圖片

  • Receiver 監聽socket、UDP端口,接收SDK發出的metrics數據
  • Msg-Parser對數據包進行反序列化,丟掉不符合規范的打點,然后將數據點暫存在Storage中
  • Storage支持7種類型的metircs指標存儲
  • Flusher在每個發送周期的整時刻,觸發任務獲取Storage的快照,并對其存儲的metrics數據進行聚合,將聚合后的數據按照發送要求進行編碼
  • Compress對編碼的數據包進行壓縮
  • Sender支持HTTP和TCP方式,將數據發給后端服務

我們將按照數據接收、數據處理、數據發送三個部分來分析Agent優化的性能熱點。

數據接收

Case 1

Agent與用戶SDK通信的時候,使用 msgpack 對數據進行序列化。它的數據格式與json類似,但在存儲時對數字、多字節字符、數組等都做了優化,減少了無用的字符,下圖是其與json的簡單對比:

圖片圖片

Agent在獲得數據后,需要通過msgpack.unpack進行反序列化,然后把數據重新組織成 std::vector。這個過程中,有兩步復制的操作,分別是:從上游數據反序列為 msgpack::object 和 msgpack::object 轉換 std::vector。

{ // Process Function
    msgpack::unpacked msg;
    msgpack::unpack(&msg, buffer.data(), buffer.size());
    msgpack::object obj = msg.get();
    std::vector<std::vector<std::string>> vecs;
    if (obj.via.array.ptr[0].type == 5) {
        std::vector<std::string> vec;
        obj.convert(&vec);
        vecs.push_back(vec);
    } else if (obj.via.array.ptr[0].type == 6) {
        obj.convert(&vecs);
    } else {
        ++fail_count;
        return result;
    }
    // Some more process steps
}

但實際上,整個數據的處理都在處理函數中。這意味著傳過來的數據在整個處理周期都是存在的,因此這兩步復制可以視為額外的開銷。

msgpack協議在對數據進行反序列化解析的時候,其內存管理的基本邏輯如下:

圖片圖片

為了避免復制 string,bin 這些類型的數據,msgpack 支持在解析的時候傳入一個函數,用來決定這些類型的數據是否需要進行復制:

圖片圖片

因此在第二步,對 msgpack::object 進行轉換的時候,我們不再轉換為 string,而是使用 string_view,可以優化掉 string 的復制和內存分配等:

// Define string_view convert struct.
template <>
struct msgpack::adaptor::convert<std::string_view> {
    msgpack::object const& operator()(msgpack::object const& o, std::string_view& v) const {
        switch (o.type) {
        case msgpack::type::BIN:
            v = std::string_view(o.via.bin.ptr, o.via.bin.size);
            break;
        case msgpack::type::STR:
            v = std::string_view(o.via.str.ptr, o.via.str.size);
            break;
        default:
            throw msgpack::type_error();
            break;
        }
        return o;
    }
};
static bool string_reference(msgpack::type::object_type type, std::size_t, void*) {
    return type == msgpack::type::STR;
}
{ 
    msgpack::unpacked msg;
    msgpack::unpack(msg, buffer.data(), buffer.size(), string_reference);
    msgpack::object obj = msg.get();
    std::vector<std::vector<std::string_view>> vecs;
    if (obj.via.array.ptr[0].type == msgpack::type::STR) {
        std::vector<std::string_view> vec;
        obj.convert(&vec);
        vecs.push_back(vec);
    } else if (obj.via.array.ptr[0].type == msgpack::type::ARRAY) {
        obj.convert(&vecs);
    } else {
        ++fail_count;
        return result;
    }
}

經過驗證可以看到:零拷貝的時候,轉換完的所有數據的內存地址都在原來的的 buffer 的內存地址范圍內。而使用 string 進行復制的時候,內存地址和 buffer 的內存地址明顯不同。

圖片圖片

Case 2

圖片圖片

Agent在接收端通過系統調用完成數據接收后,會立刻將數據投遞到異步的線程池內,進行數據的解析工作,以達到不阻塞接收端的效果。但我們在對線上數據進行分析時發現,用戶產生的數據包大小是不固定的,并且存在大量的小包(比如一條打點數據)。這會導致異步線程池內的任務數量較多,平均每個任務的體積較小,線程池需要頻繁的從隊列獲取新的任務,帶來了處理性能的下降。

因此我們充分理解了msgpack的協議格式(https://github.com/msgpack/msgpack/blob/master/spec.md)后,在接收端將多個數據小包(一條打點數據)聚合成一個數據大包(多條打點數據),進行一次任務提交,提高了接收端的處理性能,降低了線程切換的開銷。

static inline bool tryMerge(std::string& merge_buf, std::string& recv_buf, int msg_size, int merge_buf_cap) {
    uint16_t big_endian_len, host_endian_len, cur_msg_len;
    memcpy(&big_endian_len, (void*)&merge_buf[1], sizeof(big_endian_len));
    host_endian_len = ntohs(big_endian_len);
    cur_msg_len = recv_buf[0] & 0x0f;
    if((recv_buf[0] & 0xf0) != 0x90 || merge_buf.size() + msg_size > merge_buf_cap || host_endian_len + cur_msg_len > 0xffff) {
        // upper 4 digits are not 1001
        // or merge_buf cannot hold anymore data
        // or array 16 in the merge_buf cannot hold more objs (although not possible right now, but have to check)
        return false;
    }
    // start merging
    host_endian_len += cur_msg_len;
    merge_buf.append(++recv_buf.begin(), recv_buf.begin() + msg_size);
    // update elem cnt in array 16
    big_endian_len = htons(host_endian_len);
    memcpy((void*)&merge_buf[1], &big_endian_len, sizeof(big_endian_len));
    return true;
}
{ // receiver function 
    // array 16 with 0 member
    std::string merge_buf({(char)0xdc, (char)0x00, (char)0x00});
    for(int i = 0 ; i < 1024; ++i) {
        int r = recv(fd, const_cast<char *>(tmp_buffer_.data()), tmp_buffer_size_, 0);
        if (r > 0) {
            if(!tryMerge(merge_buf, tmp_buffer_, r, tmp_buffer_size_)) {
                // Submit Task
            }
        // Some other logics
    }
}

從關鍵的系統指標的角度看,在merge邏輯有收益時(接收QPS = 48k,75k,120k,150k),小包合并邏輯大大減少了上下文切換,執行指令數,icache/dcache miss,并且增加了IPC(instructions per cycle)見下表:

圖片

同時通過對前后火焰圖的對比分析看,在合并數據包之后,原本用于調度線程池的cpu資源更多的消耗在了收包上,也解釋了小包合并之后context switch減少的情況。

Case 3

用戶在打點指標中的Tags,是拼接成字符串進行純文本傳遞的,這樣設計的主要目的是簡化SDK和Agent之間的數據格式。但這種方式就要求Agent必須對字符串進行解析,將文本化的Tags反序列化出來,又由于在接收端收到的用戶打點QPS很高,這也成為了Agent的性能熱點。

早期Agent在實現這個解析操作時,采用了遍歷字符串的方式,將字符串按|=分割成 key-value 對。在其成為性能瓶頸后,我們發現它很適合使用SIMD進行加速處理。

原版

inline bool is_tag_split(const char &c) {
    return c == '|' || c == ' ';
}
inline bool is_kv_split(const char &c) {
    return c == '=';
}
bool find_str_with_delimiters(const char *str, const std::size_t &cur_idx, const std::size_t &end_idx,
    const Process_State &state, std::size_t *str_end) {
    if (cur_idx >= end_idx) {
        return false;
    }
    std::size_t index = cur_idx;
    while (index < end_idx) {
        if (state == TAG_KEY) {
            if (is_kv_split(str[index])) {
                *str_end = index;
                return true;
            } else if (is_tag_split(str[index])) {
                return false;
            }
        } else {
            if (is_tag_split(str[index])) {
                *str_end = index;
                return true;
            }
        }
        index++;
    }
    if (state == TAG_VALUE) {
        *str_end = index;
        return true;
    }
    return false;
}

SIMD

#if defined(__SSE__)
static std::size_t find_key_simd(const char *str, std::size_t end, std::size_t idx) {
    if (idx >= end) { return 0; }
    for (; idx + 16 <= end; idx += 16) {
        __m128i v = _mm_loadu_si128((const __m128i*)(str + idx));
        __m128i is_tag = _mm_or_si128(_mm_cmpeq_epi8(v, _mm_set1_epi8('|')),
                                     _mm_cmpeq_epi8(v, _mm_set1_epi8(' ')));
        __m128i is_kv = _mm_cmpeq_epi8(v, _mm_set1_epi8('='));

        int tag_bits = _mm_movemask_epi8(is_tag);
        int kv_bits = _mm_movemask_epi8(is_kv);
        // has '|' or ' ' first
        bool has_tag_first = ((kv_bits - 1) & tag_bits) != 0;
        if (has_tag_first) { return 0; }
        if (kv_bits) { // found '='
            return idx + __builtin_ctz(kv_bits);
        }
    }
    for (; idx < end; ++idx) {
        if (is_kv_split(str[idx])) { return idx; } 
        else if (is_tag_split(str[idx])) { return 0; }
    }
    return 0;
}
static std::size_t find_value_simd(const char *str, std::size_t end, std::size_t idx) {
    if (idx >= end) { return 0; }
    for (; idx + 16 <= end; idx += 16) {
        __m128i v = _mm_loadu_si128((const __m128i*)(str + idx));
        __m128i is_tag = _mm_or_si128(_mm_cmpeq_epi8(v, _mm_set1_epi8('|')),
                                     _mm_cmpeq_epi8(v, _mm_set1_epi8(' ')));
        int tag_bits = _mm_movemask_epi8(is_tag);
        if (tag_bits) {
            return idx + __builtin_ctz(tag_bits);
        }
    }
    for (; idx < end; ++idx) {
        if (is_tag_split(str[idx])) { return idx; }
    }
    return idx;
}

構建的測試用例格式為

。text 則是測試例子里的 str_size,用來測試不同 str_size 下使用 simd 的收益。可以看到,在 str_size 較大時,simd 性能明顯高于標量的實現。

str_size

simd

scalar

1

109

140

2

145

158

4

147

198

8

143

283

16

155

459

32

168

809

64

220

1589

128

289

3216

256

477

6297

512

883

12494

1024

1687

24410

數據處理

Case 1

Agent在數據聚合過程中,需要一個map來存儲一個指標的所有序列,用于對一段時間內的打點值進行聚合計算,得到一個固定間隔的觀測值。這個map的key是指標的tags,map的value是指標的值。我們通過采集火焰圖發現,這個map的查找操作存在一定程度的熱點。

圖片圖片

下面是 _M_find_before_node 的實現:

圖片圖片

這個函數作用是:算完 hash 后,在 hash 桶里找到匹配 key 的元素。這也意味著,即使命中了,hash 查找的時候也要進行一次 key 的比較操作。而在 Agent 里,這個 key 的比較操作定義為:

bool operator==(const TagSet &other) const {
        if (tags.size() != other.tags.size()) {
            return false;
        }
        for (size_t i = 0; i < tags.size(); ++i) {
            auto &left = tags[i];
            auto &right = other.tags[i];
            if (left.key_ != right.key_ || left.value_ != right.value_) {
                return false;
            }
        }
        return true;
    }

這里需要遍歷整個 Tagset 的元素并比較他們是否相等。在查找較多的情況下,每次 hash 命中后都要進行這樣一次操作是非常耗時的。可能導致時間開銷增大的原因有:

  1. 每個 tag 的 key_ 和 value_ 是單獨的內存(如果數據較短,stl 不會額外分配內存,這樣的情況下就沒有單獨分配的內存了),存在著 cache miss 的開銷,硬件預取效果也會變差;
  2. 需要頻繁地調用 memcmp 函數;
  3. 按個比較每個 tag,分支較多。

圖片圖片

因此,我們將 TagSet 的數據使用 string_view 表示,并將所有的 data 全部存放在同一塊內存中。在 dictionary encode 的時候,再把 TagSet 轉換成 string 的格式返回出去。

// TagView 
#include <functional>
#include <string>
#include <vector>
struct TagView {
    TagView() = default;
    TagView(std::string_view k, std::string_view v) : key_(k), value_(v) {}
    std::string_view key_;
    std::string_view value_;
};
struct TagViewSet {
    TagViewSet() = default;
    TagViewSet(const std::vector<TagView> &tgs, std::string&& buffer) : tags(tgs), 
        tags_buffer(std::move(buffer)) {}
    TagViewSet(std::vector<TagView> &&tgs, std::string&& buffer) { tags = std::move(tgs); }
    TagViewSet(const std::vector<TagView> &tgs, size_t buffer_assume_size) {
        tags.reserve(tgs.size());
        tags_buffer.reserve(buffer_assume_size);
        for (auto& tg : tgs) {
            tags_buffer += tg.key_;
            tags_buffer += tg.value_;
        }
        const char* start = tags_buffer.c_str();
        for (auto& tg : tgs) {
            std::string_view key(start, tg.key_.size());
            start += key.size();
            std::string_view value(start, tg.value_.size());
            start += value.size();
            tags.emplace_back(key, value);
        }
    }
    bool operator==(const TagViewSet &other) const {
        if (tags.size() != other.tags.size()) {
            return false;
        }
        // not compare every tag
        return tags_buffer == other.tags_buffer;
    }
    std::vector<TagView> tags;
    std::string tags_buffer;
};
struct TagViewSetPtrHash {
    inline std::size_t operator()(const TagViewSet *tgs) const {
        return std::hash<std::string>{}(tgs->tags_buffer);
    }
};

驗證結果表明,當 Tagset 中 kv 的個數大于 2 的時候,新方法性能較好。

圖片圖片

數據發送

Case 1

早期Agent使用zlib進行數據發送前的壓縮,隨著用戶打點規模的增長,壓縮逐步成為了Agent的性能熱點。

因此我們通過構造滿足線上用戶數據特征的數據集,對常用的壓縮庫進行了測試:

zlib使用cloudflare

圖片圖片

zlib使用1.2.11

圖片圖片

通過測試結果我們可以看到,除bzip2外,其他壓縮算法均在不同程度上優于zlib:

  • zlib的高性能分支,基于cloudflare優化 比 1.2.11的官方分支性能好,壓縮CPU開銷約為后者的37.5%
  • 采用SIMD指令加速計算
  • zstd能夠在壓縮率低于zlib的情況下,獲得更低的cpu開銷,因此如果希望獲得比當前更好的壓縮率,可以考慮zstd算法
  • 若不考慮壓縮率的影響,追求極致低的cpu開銷,那么snappy是更好的選擇

結合業務場景考慮,我們最終執行短期使用 zlib-cloudflare 替換,長期使用 zstd 替換的優化方案。

結論

上述優化取得了非常好的效果,經過上線驗證得出:

  • CPU峰值使用量降低了10.26%,平均使用量降低了6.27%
  • Mem峰值使用量降低了19.67%,平均使用量降低了19.81%

綜合分析以上性能熱點和優化方案,可以看到我們對Agent優化的主要考量點是:

  • 減少不必要的內存拷貝
  • 減少程序上下文的切換開銷,提高緩存命中率
  • 使用SIMD指令來加速處理關鍵性的熱點邏輯

除此之外,我們還在開展 PGO 和 clang thinLTO 的驗證工作,借助編譯器的能力來進一步優化Agent性能。

加入我們

本文作者趙杰裔,來自字節跳動 基礎架構-云原生-可觀測團隊,我們提供日均數十PB級可觀測性數據采集、存儲和查詢分析的引擎底座,致力于為業務、業務中臺、基礎架構建設完整統一的可觀測性技術支撐能力。同時,我們也將逐步開展在火山引擎上構建可觀測性的云產品,較大程度地輸出多年技術沉淀。 如果你也想一起攻克技術難題,迎接更大的技術挑戰,歡迎投遞簡歷到 zhaojieyi@bytedance.com

最 Nice 的工作氛圍和成長機會,福利與機遇多多,在上海、杭州和北京均有職位,歡迎加入字節跳動可觀測團隊 !

參考引用

  1. v2_0_cpp_unpacker:https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_unpacker#memory-management
  2. messagepack-specification:https://github.com/msgpack/msgpack/blob/master/spec.md
  3. Cloudflare fork of zlib with massive performance improvements:https://github.com/RJVB/zlib-cloudflare
  4. Intel? Intrinsics Guide:https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html
  5. Profile-guided optimization:https://en.wikipedia.org/wiki/Profile-guided_optimization
  6. ThinLTO:https://clang.llvm.org/docs/ThinLTO.html
責任編輯:龐桂玉 來源: 字節跳動技術團隊
相關推薦

2022-08-21 21:28:32

數據庫實踐

2022-07-12 16:54:54

字節跳動Flink狀態查詢

2022-07-18 16:02:10

數據庫實踐

2023-10-31 12:50:35

智能優化探索

2023-10-30 16:14:44

Metrics SD數據庫

2022-10-14 14:47:11

Spark字節跳動優化

2022-04-07 16:35:59

PGO 優化profile 數據編譯優化

2024-09-25 15:57:56

2025-02-28 10:10:48

2023-06-09 14:14:45

大數據容器化

2022-09-15 09:32:42

數據倉處理

2022-10-14 14:44:04

字節跳動ByteTechHTTP 框架

2022-06-07 15:33:51

Android優化實踐

2022-04-28 09:36:47

Redis內存結構內存管理

2024-04-23 10:16:29

云原生

2023-01-10 09:08:53

埋點數據數據處理

2022-10-28 13:41:51

字節SDK監控

2022-06-30 10:56:18

字節云數據庫存儲

2022-05-23 13:30:48

數據胡實踐

2017-09-11 16:34:00

點贊
收藏

51CTO技術棧公眾號

亚洲人午夜精品天堂一二香蕉| 亚洲精品乱码| 欧美一二区视频| 久久综合色视频| √新版天堂资源在线资源| 国产精品一区免费在线观看| 97av在线视频| 免费在线观看黄色小视频| 91精品国产自产在线丝袜啪| 在线中文字幕不卡| 黄色三级中文字幕| 国产精品免费播放| 成人午夜电影网站| 国产一区二区在线免费| 国产成人无码精品亚洲| 999视频精品| 日韩精品在线电影| 性一交一黄一片| 国产一区二区三区四区五区3d| 亚洲成在人线免费| 椎名由奈jux491在线播放 | 亚洲欧美激情诱惑| 久久精品国产久精国产思思| 无码人妻精品一区二区中文| 99re8这里有精品热视频8在线| 欧美三电影在线| 国产午夜福利视频在线观看| 国产午夜在线播放| 日韩欧美精品| 亚洲精品在线观看www| 亚洲 自拍 另类 欧美 丝袜| 日日夜夜亚洲| 91久久精品网| 国内外成人激情视频| 影音先锋在线播放| 中文字幕一区二区三区四区不卡| 日韩不卡av| 午夜av免费在线观看| 久久se这里有精品| 91精品国产综合久久香蕉的用户体验| 婷婷激情五月综合| 免费视频一区| 91av视频在线观看| 亚洲欧美在线观看视频| 黑人一区二区| 久久久久久成人精品| 国产这里有精品| 亚洲欧美日韩高清在线| 日韩中文字幕亚洲| 欧美xxxx精品| 日韩综合一区| 久久久精品免费| 日韩精品一区二区亚洲av性色| 偷拍欧美精品| 久久国产精品久久久| 久久久久久福利| 极品尤物久久久av免费看| 久久久久久91| 毛片在线免费视频| 日韩和的一区二区| 国产精品亚发布| 一女二男一黄一片| 国产精品自拍网站| 国产伦精品一区二区| 五月婷婷六月丁香| 国产日产欧产精品推荐色| 亚洲国产精品一区二区第一页| 福利在线午夜| 日韩理论片中文av| 国产一区 在线播放| 98色花堂精品视频在线观看| 精品久久久免费| 国产日产欧美视频| 99久久亚洲国产日韩美女| 欧美日韩国产综合草草| 自拍视频第一页| 极品束缚调教一区二区网站 | 欧美三级不卡| 久久免费视频在线观看| 日韩欧美成人一区二区三区| 欧美aa在线视频| 91国产在线免费观看| 性xxxxbbbb| 自拍偷在线精品自拍偷无码专区| 成年人网站国产| 成人性生活视频| 欧美一区二区黄| 亚洲最大免费视频| 国产精品久久久久久久久久10秀 | 欧美特黄aaaaaa| 久久99久久精品欧美| 国产99午夜精品一区二区三区| 日韩电影在线观看完整版| 国产精品进线69影院| 成人一级生活片| 欧美aaa视频| 欧美mv日韩mv国产网站| 日韩乱码人妻无码中文字幕久久| 国产精品毛片一区二区在线看| 久久久久五月天| 中文字幕一区二区人妻| 成人天堂资源www在线| 五月婷婷一区| 理论片午夜视频在线观看| 欧美日韩国产小视频在线观看| 日本精品一二三区| 99热精品久久| 日本久久91av| 日韩一区二区三区在线观看视频| 国产精品国产a级| 黄色国产精品视频| 国产精品超碰| 久久综合亚洲社区| 中文字幕在线2019| 久久综合久久鬼色中文字| 99热这里只有精品免费| 四虎国产精品永久在线国在线 | 精品国产av无码| 亚洲小说欧美另类社区| 亚洲a成v人在线观看| 川上优的av在线一区二区| 午夜免费久久看| 成人三级做爰av| 婷婷久久一区| 国产精品女人网站| 国产高清视频在线| 日韩欧美精品网址| 亚洲自拍偷拍精品| 很黄很黄激情成人| av成人免费观看| 中文字幕有码在线观看| 欧美一级日韩一级| 九九热视频在线免费观看| 麻豆精品在线观看| 日韩高清三级| 日本一区免费网站| 国产亚洲精品激情久久| 五月婷婷激情视频| 91麻豆福利精品推荐| 日韩av综合在线观看| 美腿丝袜亚洲图片| 欧美亚洲一级片| 欧美老女人性开放| 91国在线观看| 国产激情av在线| 日韩国产一区二| 先锋影音一区二区三区| 99热播精品免费| 少妇激情综合网| 国产精品久久久久久无人区| 亚洲日本一区二区| jjzz黄色片| 亚洲福利一区| 女女同性女同一区二区三区91| 黑人巨大精品| 在线观看视频亚洲| 国产又粗又猛又爽又黄的| 国产精品久久福利| 熟妇女人妻丰满少妇中文字幕| 欧美黄色一区| 国产一区自拍视频| 色老太综合网| 伊人久久久久久久久久久久久| 在线观看免费高清视频| 中文字幕一区二区日韩精品绯色| 性生活在线视频| 1024成人| 日韩福利一区二区三区| 四虎国产精品免费久久5151| 欧美激情视频在线观看| 天堂网av2014| 欧美亚洲图片小说| 欧美黑人性猛交xxx| 不卡电影免费在线播放一区| 欧美精品第三页| 亚洲精品国产首次亮相| 好吊色欧美一区二区三区四区| 日韩免费电影| 欧美成人精品h版在线观看| 熟妇人妻系列aⅴ无码专区友真希 熟妇人妻av无码一区二区三区 | 精品一区在线视频| 久久精品人人做人人爽人人| 天天综合天天添夜夜添狠狠添| 欧美三级在线| 欧美三级电影在线播放| 大胆国模一区二区三区| 久久乐国产精品| 国产黄在线看| 精品国产一区二区精华| 夜夜躁日日躁狠狠久久av| 一区二区三区精品视频| 日本激情小视频| 国产精品中文有码| 无码内射中文字幕岛国片| 欧美在线国产| 日韩一区国产在线观看| 高清一区二区三区| 国产精品一区二区久久久久| bl视频在线免费观看| 日韩性生活视频| 欧美美女色图| 亚洲国产精品va在线看黑人| 一级黄色大片免费| 欧美午夜影院在线视频| 麻豆成人在线视频| 中文字幕亚洲一区二区va在线| 99久久免费看精品国产一区| 精久久久久久久久久久| 免费观看成人在线视频| 亚洲精品精选| 97久久国产亚洲精品超碰热| 欧美成人milf| 欧美精品v日韩精品v国产精品| 日本免费一区二区视频| 国产欧美中文字幕| 久久青青视频| 97国产在线视频| 在线欧美三级| 美女少妇精品视频| 日韩精品毛片| 在线观看日韩欧美| 成年人视频在线看| 国产视频久久久| 天堂网www中文在线| 精品乱人伦小说| 国产情侣激情自拍| 欧美日韩国产高清一区二区三区 | 亚洲欧洲午夜一线一品| 天天操天天干天天操| 精品国产免费视频| 亚洲精品久久久久久无码色欲四季 | 国产精品久久国产精品99gif| 国产一二三在线| 欧美激情精品久久久久| 91香蕉在线观看| 欧美日韩爱爱视频| 91cn在线观看| 久久99青青精品免费观看| av网站大全在线| 欧美国产极速在线| 毛片在线导航| 97视频在线观看免费| 久草在线资源福利站| 欧美性受xxxx白人性爽| 亚洲黄色中文字幕| 国产ts人妖一区二区三区| 丝袜美腿一区| 国产精品国产福利国产秒拍 | 久久婷婷丁香| 麻豆传传媒久久久爱| 全部av―极品视觉盛宴亚洲| 男女污污的视频| 久久精品久久99精品久久| 一二三级黄色片| 国产成人免费视频一区| 男人的天堂影院| 91一区一区三区| 蜜桃av乱码一区二区三区| 中文字幕av一区二区三区免费看| 日本二区三区视频| 亚洲图片你懂的| 日韩毛片在线播放| 91国在线观看| 国内老熟妇对白xxxxhd| 亚洲第一中文字幕在线观看| 天堂√在线中文官网在线| 国产亚洲欧洲高清| h片在线免费| 欧美亚洲国产日韩2020| 国产综合色激情| 99三级在线| 综合干狼人综合首页| 先锋影音一区二区三区| 欧美午夜一区| 国产成人久久婷婷精品流白浆| 免播放器亚洲一区| 性猛交╳xxx乱大交| 久久日韩粉嫩一区二区三区| 日日碰狠狠添天天爽| 亚洲第一搞黄网站| 在线观看国产精品入口男同| 精品国产亚洲一区二区三区在线观看| 韩国福利在线| 久久999免费视频| 超碰超碰人人人人精品| 91久久嫩草影院一区二区| 欧美调教在线| 亚洲免费av网| 亚洲欧美日韩在线观看a三区| 五月婷婷之婷婷| 91蜜桃免费观看视频| 污污的视频在线免费观看| 欧美性极品xxxx娇小| 国产美女自慰在线观看| 国产丝袜一区二区三区免费视频 | 日本大胆欧美| 国产一区 在线播放| 美日韩一级片在线观看| 日本黄色免费观看| 日韩毛片一二三区| 欧美一区免费看| 亚洲福利视频久久| 久操视频在线| 国产精品国产三级国产aⅴ浪潮| 国产厕拍一区| 午夜在线视频免费观看| 日韩国产成人精品| 久久久久亚洲AV成人无码国产| 亚洲视频一区在线| 一本色道久久综合精品婷婷| 日韩精品在线视频美女| 国产美女一区视频| 91久久国产婷婷一区二区| 奇米影视亚洲| av动漫免费看| 久久综合九色综合欧美就去吻| 久草资源在线视频| 制服.丝袜.亚洲.中文.综合| avtt亚洲| 国产精品小说在线| 欧美日韩激情| 精品少妇无遮挡毛片| 91视视频在线观看入口直接观看www| 久久亚洲国产成人精品性色| 91精品国产品国语在线不卡| 美女黄视频在线观看| 国产精品无码专区在线观看| 国产欧美日韩精品一区二区免费 | 国产一区欧美一区| 成人信息集中地| 欧美日韩一级视频| 国产黄色免费在线观看| 国产成人av在线| 欧美色女视频| 免费看污黄网站| 国产精品私人影院| 在线观看免费观看在线| 日日噜噜噜夜夜爽亚洲精品| 国产乱子精品一区二区在线观看| 日韩欧美亚洲v片| 久久久精品性| 懂色av粉嫩av浪潮av| 欧美丝袜丝nylons| 亚洲麻豆精品| 亚洲free性xxxx护士白浆| 欧美一区在线看| 欧美图片自拍偷拍| 黄网动漫久久久| 日韩精品视频无播放器在线看| 日本在线观看天堂男亚洲| 精品国产一区二区三区香蕉沈先生 | 欧美日韩大片在线观看| 精品日韩欧美一区二区| 超黄网站在线观看| 欧美黑人3p| 奇米四色…亚洲| 欧美性x x x| 精品久久久久久久久久久久包黑料 | 成人久久久久爱| 中文字幕午夜精品一区二区三区| 伦伦影院午夜理论片| 亚洲r级在线视频| 青青国产在线| 国产自摸综合网| 激情91久久| 蜜桃av免费看| 91精品国产欧美日韩| a级片免费在线观看| 欧美国产一二三区| 国内精品视频666| 精品午夜福利在线观看| 国产香蕉一区二区三区在线视频| 亚洲综合资源| 成年人午夜视频在线观看| 国产人成一区二区三区影院| 91国产免费视频| 国内精品久久久久伊人av| 亚洲深夜福利在线观看| 在线观看国产中文字幕| 亚洲最新视频在线观看| 美丽的姑娘在线观看免费动漫| 91久久久国产精品| 一区二区国产在线观看| 91制片厂在线| 亚洲精品按摩视频| 欧美黄色网络| 久久久久久久久久久视频| 日韩毛片高清在线播放| 午夜影院免费视频| 91精品视频播放| 美女爽到呻吟久久久久| 黄色一级片中国| 一本色道久久综合狠狠躁篇怎么玩 | 色94色欧美sute亚洲13| a级在线观看| 日本一区二区三区视频在线观看| 国产精品一区在线观看乱码| 无码人妻av免费一区二区三区| 欧美大片大片在线播放| 精品国产成人|