Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 503, comments - 13, trackbacks - 0, articles - 1

          本文由微信技術(shù)團(tuán)隊(duì)仇弈彬分享,原題“微信海量數(shù)據(jù)查詢(xún)?nèi)绾螐?000ms降到100ms?”,本文進(jìn)行了內(nèi)容修訂和排版優(yōu)化。

          1、引言

          微信的多維指標(biāo)監(jiān)控平臺(tái),具備自定義維度、指標(biāo)的監(jiān)控能力,主要服務(wù)于用戶(hù)自定義監(jiān)控。作為框架級(jí)監(jiān)控的補(bǔ)充,它承載著聚合前 45億/min、4萬(wàn)億/天的數(shù)據(jù)量。

          當(dāng)前,針對(duì)數(shù)據(jù)層的查詢(xún)請(qǐng)求也達(dá)到了峰值 40萬(wàn)/min,3億/天。較大的查詢(xún)請(qǐng)求使得數(shù)據(jù)查詢(xún)遇到了性能瓶頸:查詢(xún)平均耗時(shí) > 1000ms,失敗率居高不下。

          針對(duì)大數(shù)據(jù)量帶來(lái)的查詢(xún)性能問(wèn)題,微信團(tuán)隊(duì)對(duì)數(shù)據(jù)層查詢(xún)接口進(jìn)行了針對(duì)性的優(yōu)化,將平均查詢(xún)速度從1000ms+優(yōu)化到了100ms級(jí)別。本文為各位分享優(yōu)化過(guò)程,希望對(duì)你有用!

           
           

          技術(shù)交流:

          - 移動(dòng)端IM開(kāi)發(fā)入門(mén)文章:《新手入門(mén)一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM

          - 開(kāi)源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK備用地址點(diǎn)此

          (本文已同步發(fā)布于:http://www.52im.net/thread-4629-1-1.html

          2、技術(shù)背景

          微信多維指標(biāo)監(jiān)控平臺(tái)(以下簡(jiǎn)稱(chēng)多維監(jiān)控),是具備靈活的數(shù)據(jù)上報(bào)方式、提供維度交叉分析的實(shí)時(shí)監(jiān)控平臺(tái)。

          在這里,最核心的概念是“協(xié)議”、“維度”與“指標(biāo)”。

          例如:如果想要對(duì)某個(gè)【省份】、【城市】、【運(yùn)營(yíng)商】的接口【錯(cuò)誤碼】進(jìn)行監(jiān)控,監(jiān)控目標(biāo)是統(tǒng)計(jì)接口的【平均耗時(shí)】和【上報(bào)量】。在這里,省份、城市、運(yùn)營(yíng)商、錯(cuò)誤碼,這些描述監(jiān)控目標(biāo)屬性的可枚舉字段稱(chēng)之為“維度”,而【上報(bào)量】、【平均耗時(shí)】等依賴(lài)“聚合計(jì)算”結(jié)果的數(shù)據(jù)值,稱(chēng)之為“指標(biāo)”。而承載這些指標(biāo)和維度的數(shù)據(jù)表,叫做“協(xié)議”。

          多維監(jiān)控對(duì)外提供 2 種 API:

          1)維度枚舉查詢(xún):用于查詢(xún)某一段時(shí)間內(nèi),一個(gè)或多個(gè)維度的排列組合以及其對(duì)應(yīng)的指標(biāo)值。它反映的是各維度分布“總量”的概念,可以“聚合”,也可以“展開(kāi)”,或者固定維度對(duì)其它維度進(jìn)行“下鉆”。數(shù)據(jù)可以直接生成柱狀圖、餅圖等。

          2)時(shí)間序列查詢(xún):用于查詢(xún)某些維度條件在某個(gè)時(shí)間范圍的指標(biāo)值序列。可以展示為一個(gè)時(shí)序曲線(xiàn)圖,橫坐標(biāo)為時(shí)間,縱坐標(biāo)為指標(biāo)值。

          然而,不管是用戶(hù)還是團(tuán)隊(duì)自己使用多維監(jiān)控平臺(tái)的時(shí)候,都能感受到明顯的卡頓。主要表現(xiàn)在看監(jiān)控圖像或者是查看監(jiān)控曲線(xiàn),都會(huì)經(jīng)過(guò)長(zhǎng)時(shí)間的數(shù)據(jù)加載。

          團(tuán)隊(duì)意識(shí)到:這是數(shù)據(jù)量上升必然帶來(lái)的瓶頸。

          目前:多維監(jiān)控平臺(tái)已經(jīng)接入了數(shù)千張協(xié)議表,每張表的特點(diǎn)都不同。維度組合、指標(biāo)量、上報(bào)量也不同。針對(duì)大量數(shù)據(jù)的實(shí)時(shí)聚合以及 OLAP 分析,數(shù)據(jù)層的性能瓶頸越發(fā)明顯,嚴(yán)重影響了用戶(hù)體驗(yàn)。

          于是這讓團(tuán)隊(duì)人員不由得開(kāi)始思考:難道要一直放任它慢下去嗎?答案當(dāng)然是否定的。因此,微信團(tuán)隊(duì)針對(duì)數(shù)據(jù)層的查詢(xún)進(jìn)行了優(yōu)化。

          3、優(yōu)化分析1:用戶(hù)查詢(xún)行為分析

          要優(yōu)化,首先需要了解用戶(hù)的查詢(xún)習(xí)慣,這里的用戶(hù)包含了頁(yè)面用戶(hù)和異常檢測(cè)服務(wù)。

          于是微信團(tuán)隊(duì)盡可能多地上報(bào)用戶(hù)使用多維監(jiān)控平臺(tái)的習(xí)慣,包括但不限于:常用的查詢(xún)類(lèi)型、每個(gè)協(xié)議表的查詢(xún)維度和查詢(xún)指標(biāo)、查詢(xún)量、失敗量、耗時(shí)數(shù)據(jù)等。

          在分析了用戶(hù)的查詢(xún)習(xí)慣后,有了以下發(fā)現(xiàn):

          1)時(shí)間序列查詢(xún)占比 99% 以上:

          出現(xiàn)如此懸殊的比例可能是因?yàn)椋赫{(diào)用一次維度枚舉,即可獲取所關(guān)心的各個(gè)維度。

          但是針對(duì)每個(gè)維度組合值,無(wú)論是頁(yè)面還是異常檢測(cè)都會(huì)在查詢(xún)維度對(duì)應(yīng)的多條時(shí)間序列曲線(xiàn)中,從而出現(xiàn)「時(shí)間序列查詢(xún)」比例遠(yuǎn)遠(yuǎn)高于「維度枚舉查詢(xún)」。

          2)針對(duì)1天前的查詢(xún)占比約 90%:

          出現(xiàn)這個(gè)現(xiàn)象可能是因?yàn)槊總€(gè)頁(yè)面數(shù)據(jù)都會(huì)帶上幾天前的數(shù)據(jù)對(duì)比來(lái)展示。異常檢測(cè)模塊每次會(huì)對(duì)比大約 7 天數(shù)據(jù)的曲線(xiàn),造成了對(duì)大量的非實(shí)時(shí)數(shù)據(jù)進(jìn)行查詢(xún)。

          4、優(yōu)化分析2:數(shù)據(jù)層架構(gòu)

          分析完用戶(hù)習(xí)慣,再看下目前的數(shù)據(jù)層架構(gòu)。

          多維監(jiān)控底層的數(shù)據(jù)存儲(chǔ)/查詢(xún)引擎選擇了 Apache-Druid 作為數(shù)據(jù)聚合、存儲(chǔ)的引擎,Druid 是一個(gè)非常優(yōu)秀的分布式 OLAP 數(shù)據(jù)存儲(chǔ)引擎,它的特點(diǎn)主要在于出色的預(yù)聚合能力和高效的并發(fā)查詢(xún)能力。

          它的大致架構(gòu)如圖:

          具體解釋就是:

          5、優(yōu)化分析3:為什么查詢(xún)會(huì)慢

          查詢(xún)慢的核心原因,經(jīng)微信團(tuán)隊(duì)分析如下:

          1)協(xié)議數(shù)據(jù)分片存儲(chǔ)的數(shù)據(jù)片段為 2-4h 的數(shù)據(jù),每個(gè) Peon 節(jié)點(diǎn)消費(fèi)回來(lái)的數(shù)據(jù)會(huì)存儲(chǔ)在一個(gè)獨(dú)立分片。

          2)假設(shè)異常檢測(cè)獲取 7 * 24h 的數(shù)據(jù),協(xié)議一共有 3 個(gè) Peon 節(jié)點(diǎn)負(fù)責(zé)消費(fèi),數(shù)據(jù)分片量級(jí)為 12*3*7 = 252,意味著將會(huì)產(chǎn)生 252次 數(shù)據(jù)分片 I/O。

          3)在時(shí)間跨度較大時(shí)、MiddleManager、Historical 處理查詢(xún)?nèi)菀壮瑫r(shí),Broker 內(nèi)存消耗較高。

          4)部分協(xié)議維度字段非常復(fù)雜,維度排列組合極大(>100w),在處理此類(lèi)協(xié)議的查詢(xún)時(shí),性能就會(huì)很差。

          6、優(yōu)化實(shí)踐1:拆分子查詢(xún)請(qǐng)求

          根據(jù)上面的分析,團(tuán)隊(duì)確定了初步的優(yōu)化方向:

          • 1)減少單 Broker 的大跨度時(shí)間查詢(xún);
          • 2)減少 Druid 的 Segments I/O 次數(shù);
          • 3)減少 Segments 的大小。

          在這個(gè)方案中,每個(gè)查詢(xún)都會(huì)被拆解為更細(xì)粒度的“子查詢(xún)”請(qǐng)求。例如連續(xù)查詢(xún) 7 天的時(shí)間序列,會(huì)被自動(dòng)拆解為 7 個(gè) 1天的時(shí)間序列查詢(xún),分發(fā)到多個(gè) Broker,此時(shí)可以利用多個(gè) Broker 來(lái)進(jìn)行并發(fā)查詢(xún),減少單個(gè) Broker 的查詢(xún)負(fù)載,提升整體性能。

          但是這個(gè)方案并沒(méi)有解決 Segments I/O 過(guò)多的問(wèn)題,所以需要在這里引入一層緩存。

          7、優(yōu)化實(shí)踐2:拆分子查詢(xún)請(qǐng)求+Redis Cache

          7.1概述

          這個(gè)方案相較于 v1,增加了為每個(gè)子查詢(xún)請(qǐng)求維護(hù)了一個(gè)結(jié)果緩存,存儲(chǔ)在 Redis 中(如下圖所示)。

          假設(shè)獲取 7*24h 的數(shù)據(jù),Peon 節(jié)點(diǎn)個(gè)數(shù)為 3,如果命中緩存,只會(huì)產(chǎn)生 3 次 Druid 的 Segments I/O (最近的 30min)數(shù)據(jù),相較幾百次 Segments I/O 會(huì)大幅減少。

          接下來(lái)看下具體方法。

          7.2時(shí)間序列子查詢(xún)?cè)O(shè)計(jì)

          針對(duì)時(shí)間序列的子查詢(xún),子查詢(xún)按照「天」來(lái)分解,整個(gè)子查詢(xún)的緩存也是按照天來(lái)聚合的。

          以一個(gè)查詢(xún)?yōu)槔?/strong>

          {

              "biz_id": 1, // 查詢(xún)協(xié)議表ID:1

              "formula": "avg_cost_time", // 查詢(xún)公式:求平均

              "keys": [

                  // 查詢(xún)條件:維度xxx_id=3

                  {"field": "xxx_id", "relation": "eq", "value": "3"}

              ],

              "start_time": "2020-04-15 13:23", // 查詢(xún)起始時(shí)間

              "end_time": "2020-04-17 12:00"http:// 查詢(xún)結(jié)束時(shí)間

          }

          其中 biz_id、 formula,、keys 了每個(gè)查詢(xún)的基本條件。但每個(gè)查詢(xún)各不相同,不是這次討論的重點(diǎn)。

          本次優(yōu)化的重點(diǎn)是基于查詢(xún)時(shí)間范圍的子查詢(xún)分解,而對(duì)于時(shí)間序列子查詢(xún)分解的方案則是按照「天」來(lái)分解,每個(gè)查詢(xún)都會(huì)得到當(dāng)天的全部數(shù)據(jù),由業(yè)務(wù)邏輯層來(lái)進(jìn)行合并。

          舉個(gè)例子:04-15 13:23 ~ 04-17 08:20 的查詢(xún),會(huì)被分解為 04-15、04-16、04-17 三個(gè)子查詢(xún),每個(gè)查詢(xún)都會(huì)得到當(dāng)天的全部數(shù)據(jù),在業(yè)務(wù)邏輯層找到基于用戶(hù)查詢(xún)時(shí)間的偏移量,處理結(jié)果并返回給用戶(hù)。

          每個(gè)子查詢(xún)都會(huì)先嘗試獲取緩存中的數(shù)據(jù),此時(shí)有兩種結(jié)果:

          經(jīng)過(guò)上述分析不難看出:對(duì)于距離現(xiàn)在超過(guò)一天的查詢(xún),只需要查詢(xún)一次,之后就無(wú)需訪(fǎng)問(wèn) DruidBroker 了,可以直接從緩存中獲取。

          而對(duì)于一些實(shí)時(shí)熱數(shù)據(jù),其實(shí)只是查詢(xún)了cache_update_time-threshold_time 到 end_time 這一小段的時(shí)間。在實(shí)際應(yīng)用里,這段查詢(xún)時(shí)間的跨度基本上在 20min 內(nèi),而 15min 內(nèi)的數(shù)據(jù)由 Druid 實(shí)時(shí)節(jié)點(diǎn)提供。

          7.3維度組合子查詢(xún)?cè)O(shè)計(jì)

          維度枚舉查詢(xún)和時(shí)間序列查詢(xún)不一樣的是:每一分鐘,每個(gè)維度的量都不一樣。

          而維度枚舉拿到的是各個(gè)維度組合在任意時(shí)間的總量,因此基于上述時(shí)間序列的緩存方法無(wú)法使用。在這里,核心思路依然是打散查詢(xún)和緩存。

          對(duì)此,微信團(tuán)隊(duì)使用了如下方案。

          緩存的設(shè)計(jì)采用了多級(jí)冗余模式,即每天的數(shù)據(jù)會(huì)根據(jù)不同時(shí)間粒度:天級(jí)、4小時(shí)級(jí)、1 小時(shí)級(jí)存多份,從而適應(yīng)各種粒度的查詢(xún),也同時(shí)盡量減少和 Redis 的 IO 次數(shù)。

          每個(gè)查詢(xún)都會(huì)被分解為 N 個(gè)子查詢(xún),跨度不同時(shí)間,這個(gè)過(guò)程的粗略示意圖如下:

          舉個(gè)例子:例如 04-15 13:23 ~ 04-17 08:20 的查詢(xún),會(huì)被分解為以下 10 個(gè)子查詢(xún):

          04-15 13:23 ~ 04-15 14:00

          04-15 14:00 ~ 04-15 15:00

          04-15 15:00 ~ 04-15 16:00

          04-15 16:00 ~ 04-15 20:00

          04-15 20:00 ~ 04-16 00:00

          04-16 00:00 ~ 04-17 00:00

          04-17 00:00 ~ 04-17 04:00

          04-17 00:00 ~ 04-17 04:00

          04-17 04:00 ~ 04-17 08:00

          04-17 08:00 ~ 04-17 08:20

          這里可以發(fā)現(xiàn):查詢(xún) 1 和查詢(xún) 10,絕對(duì)不可能出現(xiàn)在緩存中。因此這兩個(gè)查詢(xún)一定會(huì)被轉(zhuǎn)發(fā)到 Druid 去進(jìn)行。2~9 查詢(xún),則是先嘗試訪(fǎng)問(wèn)緩存。如果緩存中不存在,才會(huì)訪(fǎng)問(wèn) DruidBroker,在完成一次訪(fǎng)問(wèn)后將數(shù)據(jù)異步回寫(xiě)到 Redis 中。

          維度枚舉查詢(xún)和時(shí)間序列一樣,同時(shí)也用了 update_time 作為數(shù)據(jù)可信度的保障。因?yàn)樽罴?xì)粒度為小時(shí),在理想狀況下一個(gè)時(shí)間跨越很長(zhǎng)的請(qǐng)求,實(shí)際上訪(fǎng)問(wèn) Druid 的最多只有跨越 2h 內(nèi)的兩個(gè)首尾部查詢(xún)而已。

          8、優(yōu)化實(shí)踐3:更進(jìn)一步(子維度表)

          通過(guò)子查詢(xún)緩存方案,我們已經(jīng)限制了 I/O 次數(shù),并且保障 90% 的請(qǐng)求都來(lái)自于緩存。但是維度組合復(fù)雜的協(xié)議,即 Segments 過(guò)大的協(xié)議,仍然會(huì)消耗大量時(shí)間用于檢索數(shù)據(jù)。

          所以核心問(wèn)題在于:能否進(jìn)一步降低 Segments 大小?

          維度爆炸問(wèn)題在業(yè)界都沒(méi)有很好的解決方案,大家要做的也只能是盡可能規(guī)避它,因此這里,團(tuán)隊(duì)在查詢(xún)層實(shí)現(xiàn)了子維度表的拆分以盡可能解決這個(gè)問(wèn)題,用空間換時(shí)間。

          具體做法為:

          • 1) 對(duì)于維度復(fù)雜的協(xié)議,抽離命中率高的低基數(shù)維度,建立子維度表,實(shí)時(shí)消費(fèi)并入庫(kù)數(shù)據(jù);
          • 2) 查詢(xún)層支持按照用戶(hù)請(qǐng)求中的查詢(xún)維度,匹配最小的子維度表。

          9、優(yōu)化成果

          9.1緩存命中率>85%

          在做完所有改造后,最重要的一點(diǎn)便是緩存命中率。因?yàn)榇蟛糠值恼?qǐng)求來(lái)自于1天前的歷史數(shù)據(jù),這為緩存命中率提供了保障。

          具體是:

          • 1)子查詢(xún)緩存完全命中率(無(wú)需查詢(xún)Druid):86%;
          • 2)子查詢(xún)緩存部分命中率(秩序查詢(xún)?cè)隽繑?shù)據(jù)):98.8%。

          9.2查詢(xún)耗時(shí)優(yōu)化至 100ms

          在整體優(yōu)化過(guò)后,查詢(xún)性能指標(biāo)有了很大的提升:

          平均耗時(shí) 1000+ms -> 140ms;P95:5000+ms -> 220ms。

           

          10、相關(guān)文章

          [1] 微信后臺(tái)基于時(shí)間序的海量數(shù)據(jù)冷熱分級(jí)架構(gòu)設(shè)計(jì)實(shí)踐

          [2] IM開(kāi)發(fā)基礎(chǔ)知識(shí)補(bǔ)課(三):快速理解服務(wù)端數(shù)據(jù)庫(kù)讀寫(xiě)分離原理及實(shí)踐建議

          [3] 社交軟件紅包技術(shù)解密(六):微信紅包系統(tǒng)的存儲(chǔ)層架構(gòu)演進(jìn)實(shí)踐

          [4] 微信后臺(tái)基于時(shí)間序的新一代海量數(shù)據(jù)存儲(chǔ)架構(gòu)的設(shè)計(jì)實(shí)踐

          [5] 陌陌技術(shù)分享:陌陌IM在后端KV緩存架構(gòu)上的技術(shù)實(shí)踐

          [6] 現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲(chǔ)方案探討

          [7] 微信海量用戶(hù)背后的后臺(tái)系統(tǒng)存儲(chǔ)架構(gòu)(視頻+PPT) [附件下載]

          [8] 騰訊TEG團(tuán)隊(duì)原創(chuàng):基于MySQL的分布式數(shù)據(jù)庫(kù)TDSQL十年鍛造經(jīng)驗(yàn)分享

          [9] IM全文檢索技術(shù)專(zhuān)題(四):微信iOS端的最新全文檢索技術(shù)優(yōu)化實(shí)踐

          [10] 微信Windows端IM消息數(shù)據(jù)庫(kù)的優(yōu)化實(shí)踐:查詢(xún)慢、體積大、文件損壞等

          [11] 微信技術(shù)分享:揭秘微信后臺(tái)安全特征數(shù)據(jù)倉(cāng)庫(kù)的架構(gòu)設(shè)計(jì)

          [12] 現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲(chǔ)方案探討

          11、微信團(tuán)隊(duì)的其它文章

          Android版微信安裝包“減肥”實(shí)戰(zhàn)記錄

          iOS版微信安裝包“減肥”實(shí)戰(zhàn)記錄

          移動(dòng)端IM實(shí)踐:iOS版微信界面卡頓監(jiān)測(cè)方案

          微信“紅包照片”背后的技術(shù)難題

          IPv6技術(shù)詳解:基本概念、應(yīng)用現(xiàn)狀、技術(shù)實(shí)踐(上篇)

          微信技術(shù)分享:微信的海量IM聊天消息序列號(hào)生成實(shí)踐(算法原理篇)

          微信團(tuán)隊(duì)分享:Kotlin漸被認(rèn)可,Android版微信的技術(shù)嘗鮮之旅

          社交軟件紅包技術(shù)解密(二):解密微信搖一搖紅包從0到1的技術(shù)演進(jìn)

          社交軟件紅包技術(shù)解密(十一):解密微信紅包隨機(jī)算法(含代碼實(shí)現(xiàn))

          QQ設(shè)計(jì)團(tuán)隊(duì)分享:新版 QQ 8.0 語(yǔ)音消息改版背后的功能設(shè)計(jì)思路

          微信團(tuán)隊(duì)分享:極致優(yōu)化,iOS版微信編譯速度3倍提升的實(shí)踐總結(jié)

          IM“掃一掃”功能很好做?看看微信“掃一掃識(shí)物”的完整技術(shù)實(shí)現(xiàn)

          微信團(tuán)隊(duì)分享:微信支付代碼重構(gòu)帶來(lái)的移動(dòng)端軟件架構(gòu)上的思考

          IM開(kāi)發(fā)寶典:史上最全,微信各種功能參數(shù)和邏輯規(guī)則資料匯總

          微信團(tuán)隊(duì)分享:微信直播聊天室單房間1500萬(wàn)在線(xiàn)的消息架構(gòu)演進(jìn)之路

          企業(yè)微信的IM架構(gòu)設(shè)計(jì)揭秘:消息模型、萬(wàn)人群、已讀回執(zhí)、消息撤回等

          微信團(tuán)隊(duì)分享:微信后臺(tái)在海量并發(fā)請(qǐng)求下是如何做到不崩潰的

          IM跨平臺(tái)技術(shù)學(xué)習(xí)(九):全面解密新QQ桌面版的Electron內(nèi)存優(yōu)化實(shí)踐

          企業(yè)微信針對(duì)百萬(wàn)級(jí)組織架構(gòu)的客戶(hù)端性能優(yōu)化實(shí)踐

          揭秘企業(yè)微信是如何支持超大規(guī)模IM組織架構(gòu)的——技術(shù)解讀四維關(guān)系鏈

          微信團(tuán)隊(duì)分享:詳解iOS版微信視頻號(hào)直播中因幀率異常導(dǎo)致的功耗問(wèn)題


          (本文已同步發(fā)布于:http://www.52im.net/thread-4629-1-1.html



          作者:Jack Jiang (點(diǎn)擊作者姓名進(jìn)入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時(shí)通訊開(kāi)發(fā)交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時(shí)是【原創(chuàng)Java Swing外觀(guān)工程BeautyEye】【輕量級(jí)移動(dòng)端即時(shí)通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處(也可前往 我的52im.net 找到我)。


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 敦化市| 明光市| 克什克腾旗| 犍为县| 凤冈县| 伊春市| 台江县| 彰化市| 霍邱县| 淮北市| 聂荣县| 曲松县| 朔州市| 深水埗区| 龙江县| 晋城| 金秀| 肇庆市| 周宁县| 塔河县| 阜康市| 从化市| 当涂县| 沧州市| 西昌市| 四平市| 都江堰市| 鸡东县| 岳阳县| 榆中县| 揭西县| 和静县| 如东县| 绵阳市| 北川| 吉林市| 象山县| 老河口市| 雅江县| 锦屏县| 水城县|