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

聊聊 Redis 集群數據遷移

數據庫 Redis
?本文是筆者對于Redis?源碼分析的一個階段,將從源碼分析的角度讓讀者深入了解Redis節點遷移的工作流程,希望對你有幫助。


詳解redis cluster數據遷移過程

節點基本結構定義

redis集群提供16384個slot,我們可以按需分配給節點上,后續進行鍵值對存儲時,我們就可以按照算法將鍵值對存到對應slot上的redis服務器上:

集群節點本質就是通過slots這個數組記錄當前節點的所管理的情況,這里我們可以看到slots是一個char 數組,長度為REDIS_CLUSTER_SLOTS(16384)除8,這樣做的原因是因為:

  • char占1個字節,每個字節8位。
  • 每個char可以記錄8個slot的情況,如果是自己的slot則對應char的某一個位置記錄為1:

我們以node-1為例,因為它負責0-5460的節點,所以它的slots0-5460都為1,對應的圖解如下所示,可以看到筆者這里省略了后半部分,僅僅表示了0-15位置為1:

對此我們也給出這段redis中節點的定義,即位于cluster.h中的clusterNode這個結構體中,可以看slots這段定義:

typedef struct clusterNode {
  //......
    //記錄集群負責的槽,總的為16384
    unsigned char slots[REDIS_CLUSTER_SLOTS/8]; 
    //......
}

設置slot后續節點走向

以本文示例為例,我們希望后續節點2的數據全部存到節點1中,那么我們首先需要鍵入如下兩條配置:

# 在節點1上執行,將節點2數據導入到節點1上
 CLUSTER SETSLOT 3 IMPORTING node2
 # 在節點2上執行,將自己的數據遷移到節點1
 CLUSTER SETSLOT 3 MIGRATING node1

這兩條指最終都會被各自的服務端解析,并調用clusterCommand執行,我們以節點1導入為例,假設我們執行clusterCommand解析到setslot 關鍵字和importing關鍵字,即知曉要導入其他節點的數據。對應的節點1就會通過importing_slots_from數組標記自己將導入這個slot的數據,而節點2也會通過migrating_slots_to數組標記自己要將數據導出給其他節點的slot:

對此我們給出clusterCommand的執行流程,可以看到該函數解析出migrating或者importing關鍵字時就會將對的migrating_slots_to或者importing_slots_from數組對應slot位置的索引位置設置為當前上述命令傳入的node id:

void clusterCommand(redisClient *c) {
     //......

        if (!strcasecmp(c->argv[3]->ptr,"migrating") && c->argc == 5) {//處理遷出的邏輯
            //看看自己是否有遷出的slot,沒有則報錯
            if (server.cluster->slots[slot] != myself) {
                addReplyErrorFormat(c,"I'm not the owner of hash slot %u",slot);
                return;
            }
            //查看自己是否知曉這個node id,如果沒有則報錯
            if ((n = clusterLookupNode(c->argv[4]->ptr)) == NULL) {
                addReplyErrorFormat(c,"I don't know about node %s",
                    (char*)c->argv[4]->ptr);
                return;
            }
            //標記遷出到slot為傳入的node
            server.cluster->migrating_slots_to[slot] = n;
        } else if (!strcasecmp(c->argv[3]->ptr,"importing") && c->argc == 5) {//處理遷入的邏輯
            //查看遷入的slot是否已經配置,如果有則報錯
            if (server.cluster->slots[slot] == myself) {
                addReplyErrorFormat(c,
                    "I'm already the owner of hash slot %u",slot);
                return;
            }
            //查看自己是否知曉要遷入數據的node的信息,如果不知道則報錯
            if ((n = clusterLookupNode(c->argv[4]->ptr)) == NULL) {
                addReplyErrorFormat(c,"I don't know about node %s",
                    (char*)c->argv[3]->ptr);
                return;
            }
            //標記遷入slot位置為傳入的nodeid
            server.cluster->importing_slots_from[slot] = n;
        } //......
}

后續的我們假設還是將set key value請求發送到節點2,因為上述命令的原因,節點會返回move/ask告知客戶端這個鍵值對現在要存到節點1上。對應節點1收到這個key請求時,通過key計算得slot正是自己,它就會將這個鍵值對存儲到自己的數據庫中:

這里我們以節點1的角度查看這個問題,當客戶端收到move指令后,繼續向節點1發送指令,節點1通過收到指令調用processCommand,其內部調用getNodeByQuery獲取當前key對應的slot,發現是自己則直接存儲數據到當前節點的內存數據庫中:

int processCommand(redisClient *c) {
    //......
    //如果開啟了集群模式,且發送者不是master且參數帶key則進入邏輯
    if (server.cluster_enabled &&
        !(c->flags & REDIS_MASTER) &&
        !(c->flags & REDIS_LUA_CLIENT &&
          server.lua_caller->flags & REDIS_MASTER) &&
        !(c->cmd->getkeys_proc == NULL && c->cmd->firstkey == 0))
    {
        int hashslot;

        if (server.cluster->state != REDIS_CLUSTER_OK) {
           //......
        } else {
            int error_code;
            //查找鍵值對對應的slot和這個slot負責的節點
            clusterNode *n = getNodeByQuery(c,c->cmd,c->argv,c->argc,&hashslot,&error_code);
            //如果為空且或者非自己,則轉交出去給別人處理
            if (n == NULL || n != server.cluster->myself) {
                flagTransaction(c);
                clusterRedirectClient(c,n,hashslot,error_code);
                return REDIS_OK;
            }
        }
    }
 //......
 //將鍵值對存儲到當前數據庫中
}

我們以節點的視角再次直接步入getNodeByQuery查看這段邏輯,可以看到其內部會基于key計算slot然后將得到對應的node,如果發現這個node是自己且屬于importing_slots_from,即說明是客戶端通過move或者ask請求找到自己的,則進行進一步是否是多條指令執行且存在key找不到存儲位置的情況,若存在則返回空,反之都是直接返回當前節點信息,即node2的新數據直接遷移過來:

clusterNode *getNodeByQuery(redisClient *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *error_code) {
    //......
    //遍歷命令
    for (i = 0; i < ms->count; i++) {
       //.....
  //獲取指令、參數個數、參數
        mcmd = ms->commands[i].cmd;
        margc = ms->commands[i].argc;
        margv = ms->commands[i].argv;
        //解析出key以及個數
        keyindex = getKeysFromCommand(mcmd,margv,margc,&numkeys);
        for (j = 0; j < numkeys; j++) {
            //拿到key
            robj *thiskey = margv[keyindex[j]];
            //計算slot
            int thisslot = keyHashSlot((char*)thiskey->ptr,
                                       sdslen(thiskey->ptr));

             //.....
                //如果就是當前節點正在做遷出或者遷入,則migrating_slot/importing_slot設置為1
                if (n == myself &&
                    server.cluster->migrating_slots_to[slot] != NULL)
                {
                    migrating_slot = 1;
                } else if (server.cluster->importing_slots_from[slot] != NULL) {
                    importing_slot = 1;
                }
            } else {
               //.....
//.....
        }
      //.....
    }
 //如果設置了導入標識為1且標識為asking則步入這段邏輯,
 if (importing_slot &&
        (c->flags & REDIS_ASKING || cmd->flags & REDIS_CMD_ASKING))
    { //當前指令有多個key且存在未命中的則返回空,反之返回自己
        if (multiple_keys && missing_keys) {
            if (error_code) *error_code = REDIS_CLUSTER_REDIR_UNSTABLE;
            return NULL;
        } else {
            return myself;
        }
    }

    //.....
    //返回節點信息以本示例來說就是返回當前節點信息
    return n;
}

完成節點遷移

上述操作僅僅針對新節點的遷移,對于舊的節點我們就需要通過節點2鍵入CLUSTER GETKEYSINSLOT slot count要遷移的舊的key的slot,然后通過MIGRATE host port key dbid timeout [COPY | REPLACE]將數據遷移到節點1上。 這里我們補充一下MIGRATE 中copy和replace的區別,前者是遇到重復直接報錯,后者是遷移時直接覆蓋。 最終這條指令回基于要遷移的key而生成一條RESTORE-ASKING key ttl serialized-value [REPLACE] [ABSTTL] [IDLETIME seconds] [FREQ frequency]指令發送給導入的節點,以本文例子來說就是節點1:

這里我們給出MIGRATE 指令對應的處理函數migrateCommand,邏輯和我上文說的差不多,基于指令解析出replace或者copy等信息,然后用argv[3]即我們的key得出這個鍵值對的信息生成RESTORE指令將鍵值對轉存給節點1:

/* 命令 MIGRATE host port key dbid timeout [COPY | REPLACE] */
void migrateCommand(redisClient *c) {
   
    //......
    //解析拷貝和替代選項,前者重復會報錯
    for (j = 6; j < c->argc; j++) {
        if (!strcasecmp(c->argv[j]->ptr,"copy")) {
            copy = 1;
        } else if (!strcasecmp(c->argv[j]->ptr,"replace")) {
            replace = 1;
        } else {
            addReply(c,shared.syntaxerr);
            return;
        }
    }

  //......
    //查看要遷移的key是否存在嗎,如果不存則直接報錯返回
    if ((o = lookupKeyRead(c->db,c->argv[3])) == NULL) {
        addReplySds(c,sdsnew("+NOKEY\r\n"));
        return;
    }

    /* Connect */
    //建立socket連接
    cs = migrateGetSocket(c,c->argv[1],c->argv[2],timeout);
    //......

    //cmd初始化一個buf緩沖區
    rioInitWithBuffer(&cmd,sdsempty());

    /* Send the SELECT command if the current DB is not already selected. */
    //如果尚未選擇當前DB,則發送SELECT命令。
    int select = cs->last_dbid != dbid; /* Should we emit SELECT? */
    if (select) {
        redisAssertWithInfo(c,NULL,rioWriteBulkCount(&cmd,'*',2));
        redisAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"SELECT",6));
        redisAssertWithInfo(c,NULL,rioWriteBulkLongLong(&cmd,dbid));
    }

    /* Create RESTORE payload and generate the protocol to call the command. */
    //獲取key的過期時效
    expireat = getExpire(c->db,c->argv[3]);
    if (expireat != -1) {
        ttl = expireat-mstime();
        if (ttl < 1) ttl = 1;
    }
 
    //集群用RESTORE-ASKING發送key給目標
    if (server.cluster_enabled)
        redisAssertWithInfo(c,NULL,
            rioWriteBulkString(&cmd,"RESTORE-ASKING",14));
    else
        redisAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"RESTORE",7));
   //填充key和value ttl等
    redisAssertWithInfo(c,NULL,sdsEncodedObject(c->argv[3]));
    redisAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,c->argv[3]->ptr,
            sdslen(c->argv[3]->ptr)));
    redisAssertWithInfo(c,NULL,rioWriteBulkLongLong(&cmd,ttl));

   //......
    //遷移指令字符串寫入緩沖區
    redisAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,payload.io.buffer.ptr,
                                sdslen(payload.io.buffer.ptr)));
   //......
    //如果是replace發出 REPLACE
    if (replace)
        redisAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"REPLACE",7));

  

 //......
}

最后調整

最后我們只需在節點1和2都執行CLUSTER SETSLOT <SLOT> NODE <NODE ID> 完成slot指派,這指令最終就會走到clusterCommand中,節點1和節點2格子的處理邏輯為:

  • 節點2看看遷移的key是否不存則且migrating_slots_to數據不為空,若符合要求說明遷移完成但狀態未修改,直接將migrating_slots_to置空完成指派最后調整。
  • 節點1查看節點id是否是自己且importing_slots_from是否有數據,若有則說明節點導入完成,直接將importing_slots_from置空。
void clusterCommand(redisClient *c) {
    //......
     else if (!strcasecmp(c->argv[1]->ptr,"setslot") && c->argc >= 4) {//處理setslot指令
          //......
   else if (!strcasecmp(c->argv[3]->ptr,"node") && c->argc == 5) {
            /* CLUSTER SETSLOT <SLOT> NODE <NODE ID> 標記最終遷移的節點 */
            clusterNode *n = clusterLookupNode(c->argv[4]->ptr);

           //......
            //如果發現對應的key為0,且migrating_slots_to不為空,則說明遷出完成但狀態還未修改,節點2會將migrating_slots_to設置為空
            if (countKeysInSlot(slot) == 0 &&
                server.cluster->migrating_slots_to[slot])
                server.cluster->migrating_slots_to[slot] = NULL;

           //如果是節點1則會看指令的nodeid是否是自己且importing_slots_from是否有數據,若有則說明導入成功直接將importing_slots_from設置為空
            if (n == myself &&
                server.cluster->importing_slots_from[slot])
            {
              //......
                server.cluster->importing_slots_from[slot] = NULL;
            }
           
        }
  //......
}
責任編輯:趙寧寧 來源: 寫代碼的SharkChili
相關推薦

2025-02-24 10:07:09

Redis節點遷移集群

2022-02-06 21:14:57

Redis命令

2022-02-09 15:36:49

Redis主從模式哨兵模式

2020-04-21 22:59:50

Redis搭建選舉

2024-09-11 20:05:56

2022-08-28 19:36:15

數據分片KafkaRocketMQ

2021-06-26 07:40:45

Greenplum集群部署

2018-02-02 16:15:02

Hadoop數據遷移集群

2025-03-03 10:25:10

2022-05-09 07:35:48

動態集群限流

2024-01-15 16:51:03

Redis數據存儲

2022-03-03 09:51:11

RedisCouchbase數據存儲

2020-04-09 11:56:10

Elasticsear集群硬件

2023-02-01 13:22:00

數據庫表連接SQL

2021-01-26 07:11:26

Redis數據同步數據遷移

2020-09-24 06:49:34

PythonRedis

2024-07-25 08:39:48

2022-06-21 07:51:06

Redis高可用哨兵進程

2024-10-23 08:13:30

Spring響應式編程

2023-04-06 08:00:36

VPC虛擬私有云Amazon
點贊
收藏

51CTO技術棧公眾號

日韩av电影在线免费播放| 亚洲国产精品电影在线观看| 一本一道久久a久久综合精品| 91中文字幕在线视频| 黄色在线一区| 亚洲视频第一页| av电影中文字幕| 午夜无码国产理论在线| 夜夜嗨av一区二区三区中文字幕 | www.色国产| 91精品国偷自产在线电影| 亚洲精品456在线播放狼人| 午夜激情福利在线| 91超碰在线播放| 国产精品国产三级国产有无不卡| 黑人另类av| 国产毛片久久久久| 日韩国产欧美在线视频| 欧美激情中文字幕乱码免费| 欧美另类69xxxx| 欧美色图五月天| 日韩午夜精品视频| 日韩欧美国产片| 成人影院入口| 亚洲成人资源网| 三上悠亚免费在线观看| 成人午夜电影在线观看| 91视频在线观看免费| 99久久久精品免费观看国产| 一级特黄aaaaaa大片| 久久久久久久波多野高潮日日| 欧美日韩第一页| 三级黄色免费观看| 欧美亚洲高清| 一区二区三区四区精品| 日韩中文字幕电影| 五月综合久久| 国产婷婷色综合av蜜臀av| 久久久男人的天堂| 91精品国产自产在线丝袜啪| 日韩一区二区三区电影在线观看| 免费av不卡在线| 日本精品久久| 欧美男同性恋视频网站| 天天综合网日韩| 欧美日韩尤物久久| 欧美午夜精品久久久久久超碰| 999精品网站| 欧美无毛视频| 在线视频你懂得一区二区三区| www.爱色av.com| 一区二区三区短视频| 福利二区91精品bt7086| 日韩免费一级视频| 午夜不卡影院| 色哟哟一区二区三区| 国产激情在线观看视频| 午夜精品久久久久久久久久蜜桃| 色综合久久久久久久| 别急慢慢来1978如如2| 色8久久影院午夜场| 欧美三级电影网| 欧美性受xxxxxx黑人xyx性爽| 91精品福利观看| 欧美一区二区三区免费大片| 国产ts在线观看| 欧美wwwsss9999| 亚洲一区999| 2014亚洲天堂| 国产精品videossex久久发布| 久久久久中文字幕| 婷婷激情五月网| 日本视频在线一区| 国产日韩精品一区二区| 精品久久在线观看| 99视频在线观看一区三区| 欧美视频1区| 毛片在线视频| 亚洲一区二区三区四区不卡| 中文字幕乱码人妻综合二区三区 | 懂色av一区二区三区在线播放| 朝桐光av在线一区二区三区| 99久久婷婷国产综合精品| 免费在线观看91| 免费在线观看av网站| 亚洲自拍与偷拍| 农村妇女精品一二区| 日韩五码电影| 亚洲国产三级网| 特级西西人体高清大胆| 欧美国产激情| 国产精品成人一区二区| www.国产三级| 国产亚洲婷婷免费| 成人在线视频一区二区三区| 国产精品一区二区av影院萌芽| 欧美丰满少妇xxxbbb| xxxwww国产| 久久在线电影| 欧美一区二区三区精品电影| 一级做a爱片久久毛片| av不卡一区二区三区| 亚洲蜜桃av| 在线观看欧美日韩电影| 日韩三级av在线播放| 特级西西www444人体聚色| 欧美日一区二区三区在线观看国产免| 日韩av电影免费观看高清| 99久久精品无免国产免费| 国产性色一区二区| 人妻少妇精品无码专区二区 | 欧美日韩一区成人| 国产精品久久不卡| 欧美啪啪一区| 国产欧美一区二区三区视频| 久久精品色图| 午夜视频一区二区| 国产黑丝在线视频| 色婷婷综合网| 国产成人中文字幕| 四虎在线观看| 黄色一区二区在线| 中国xxxx性xxxx产国| 一区二区日韩欧美| 国产欧美精品一区二区三区-老狼| 人成在线免费视频| 性欧美疯狂xxxxbbbb| 无码人妻少妇色欲av一区二区| 日韩国产一区二区三区| 日本高清+成人网在线观看| 韩国av在线免费观看| 亚洲激情av在线| 日韩精品aaa| 99精品全国免费观看视频软件| 国产精品美乳一区二区免费 | 国产亚洲制服色| 国产91对白刺激露脸在线观看| 久久久久久久久久久久久久久久久久久久| 久久国产精品视频| 国产丝袜在线视频| 亚洲精品久久嫩草网站秘色| 国产资源中文字幕| 午夜精品999| 99久久国产免费免费| 精品精品导航| 精品国产乱码久久久久久1区2区| 国产极品国产极品| 国产高清久久久久| 欧美黑人在线观看| jazzjazz国产精品麻豆| 欧美激情精品久久久久久变态| www.成人在线观看| 亚洲电影在线免费观看| 少妇一级淫免费观看| 99国产精品视频免费观看一公开 | 免费在线超碰| 欧美三级电影网站| 亚洲综合网在线| 粉嫩13p一区二区三区| 男人添女荫道口女人有什么感觉| 哺乳一区二区三区中文视频| 88xx成人精品| 国产高清一区在线观看| 欧美日韩五月天| 欧美日韩午夜视频| 成人毛片老司机大片| 女人天堂av手机在线| 国产亚洲一区| 成人国产精品久久久| 精精国产xxxx视频在线中文版| 亚洲高清久久网| 欧美视频xxxx| 亚洲免费观看高清完整版在线观看熊 | 久久一区二区精品| 国产成人精品一区二区三区在线| 久久成人av网站| 午夜激情在线视频| 欧美日韩欧美一区二区| 免费一级肉体全黄毛片| 91视频免费观看| jizz18女人| 伊人蜜桃色噜噜激情综合| 欧美极品jizzhd欧美| 欧美天堂一区二区| 久久免费观看视频| avtt亚洲| 日韩成人xxxx| 91成年人视频| 狠狠做深爱婷婷久久综合一区| 人妻互换一区二区激情偷拍| 丁香网亚洲国际| 亚洲综合色在线观看| 黑丝一区二区| 日本一区精品| av综合网站| 国产精品久在线观看| segui88久久综合| 中文国产亚洲喷潮| 五月天婷婷视频| 91精品国产综合久久精品图片| 日本熟妇色xxxxx日本免费看| 欧美激情中文字幕| 7788色淫网站小说| 国产麻豆精品theporn| 久久精品午夜福利| 亚洲视频久久| 香蕉精品视频在线| 久久av资源| 国产伦精品一区二区三区免费视频| 久久久国产精品网站| 奇门遁甲1982国语版免费观看高清| 综合久久2o19| 最新国产精品拍自在线播放| 亚洲人妻一区二区三区| 日韩丝袜情趣美女图片| 中文字幕一区二区三区四区视频| 精品日本高清在线播放 | av在线收看| 国产丝袜视频一区| 亚洲国产精品二区| 欧美丰满美乳xxx高潮www| 中文字幕+乱码+中文| 欧美日韩在线观看视频| 国产在线观看你懂的| 亚洲欧美一区二区三区极速播放 | 亚洲一区在线观看免费 | 96sao精品视频在线观看| 亚洲四虎影院| 国产成人免费av电影| 免费h在线看| 欧美一级大片在线观看| 成年网站在线视频网站| 欧美国产在线电影| 污片在线免费观看| 美女国内精品自产拍在线播放| www.黄在线观看| 伊人亚洲福利一区二区三区| 国产综合在线观看| 亚洲欧美综合图区| 国内在线免费高清视频| 亚洲男人天堂久| 视频午夜在线| 亚洲网站在线播放| 激情小视频在线| 亚洲天堂2020| 在线免费看黄网站| 日韩中文字幕亚洲| 国产原创视频在线观看| 久久中文字幕一区| 日韩123区| 午夜免费日韩视频| 色戒汤唯在线观看| 日韩美女免费观看| 电影亚洲一区| 亚洲iv一区二区三区| 日本在线成人| 国产精品久久精品视| 美女视频亚洲色图| 欧美少妇一区| 午夜精品毛片| 国产日韩av网站| 亚洲国内自拍| 美女网站免费观看视频| 九九国产精品视频| 任你躁av一区二区三区| 99re成人在线| 国产精品视频在| 亚洲男人天堂av| 国产成人啪精品午夜在线观看| 欧美日韩国产精品一区二区不卡中文 | 波多野结衣影院| 日本一区二区在线不卡| 动漫性做爰视频| 性欧美疯狂xxxxbbbb| 波多野结衣理论片| 91精品国产一区二区三区| 手机在线观看毛片| 尤物yw午夜国产精品视频| 岛国中文字幕在线| 91精品国产99| 日本久久一区| 久久偷窥视频| 99久久99视频只有精品| 浮妇高潮喷白浆视频| 久久99精品久久久久久| 国产婷婷在线观看| 日本一区免费视频| 日本五十熟hd丰满| 欧美日韩aaaaaa| 亚洲欧美自偷自拍| 日韩中文字幕在线观看| 91制片在线观看| 国产精品亚洲欧美导航| 日韩中出av| 麻豆传媒网站在线观看| 久热国产精品| 师生出轨h灌满了1v1| 欧美国产日韩亚洲一区| 久久免费在线观看视频| 欧美少妇bbb| 亚洲日本香蕉视频| 欧美成人第一页| 国产精品毛片久久久久久久久久99999999| 91pron在线| 色喇叭免费久久综合网| 凹凸国产熟女精品视频| 国产精品一区二区男女羞羞无遮挡| 国产精品无码一区二区三区| 亚洲最大色网站| 97超碰人人草| 在线精品视频视频中文字幕| 人人草在线视频| 国产精品成人观看视频免费| 我不卡手机影院| 国产wwwxx| 26uuu成人网一区二区三区| 欧美国产精品一二三| 欧美喷水一区二区| 国产大片在线免费观看| 欧美一区在线直播| 99热这里只有精品首页 | 奇米777日韩| 国产精品久久久对白| 久久精品久久久| 久久人人爽av| 国产精品午夜久久| 久久亚洲精品石原莉奈| 精品亚洲国产成av人片传媒| 国语对白在线刺激| 成人女人免费毛片| 欧美在线免费| 国产裸体视频网站| 亚洲欧美国产三级| 国产女人高潮时对白| 日韩中文在线不卡| 狂野欧美性猛交xxxx| 亚洲成人第一| 青青草97国产精品免费观看| 免费看裸体网站| 在线观看免费成人| 搞黄视频免费在线观看| 国产精品久久久久久av福利软件| 国产日产精品一区二区三区四区的观看方式 | 在线免费观看麻豆| 日韩欧中文字幕| 邻家有女韩剧在线观看国语| 国产成人精品999| 国产成人精品一区二区免费看京 | a成人v在线| 亚洲人成网站在线观看播放| 裸体一区二区三区| 国产精品99久久久久久成人| 日韩欧美自拍偷拍| 免费在线中文字幕| 久久99精品久久久久久久久久| 亚洲制服少妇| 久久久久久久久福利| 91麻豆精品国产自产在线| 18videosex性欧美麻豆| 国产精品成人一区二区三区| 亚洲免费影视| 日本免费www| 日韩欧美中文字幕公布| 91九色国产在线播放| 你懂的网址一区二区三区| 青青青爽久久午夜综合久久午夜| 精品国产精品国产精品| 精品裸体舞一区二区三区| 女厕盗摄一区二区三区| 视频在线99re| 国产精品 日产精品 欧美精品| 日韩少妇高潮抽搐| 中文字幕免费精品一区| 精品视频成人| 91视频最新入口| 国产精品嫩草久久久久| 精品人妻一区二区三区蜜桃| 69久久夜色精品国产69乱青草| 国语产色综合| 超碰人人cao| 色婷婷综合久久久久中文| 国产在线69| 欧美lavv| 国产福利一区二区三区| 欧美日韩综合一区二区三区| 日韩视频永久免费观看| 卡一精品卡二卡三网站乱码 | 亚洲欧美在线视频免费| 国产午夜一区二区| 伊人久久大香线蕉av超碰| av天堂永久资源网| 亚洲毛片av在线| 国产视频精品久久| 国产aⅴ精品一区二区三区黄| 日日夜夜精品免费视频| 国语对白一区二区| 中文字幕在线视频日韩| 欧美日韩一本| 男生和女生一起差差差视频| 在线视频一区二区三|