分享 : 警惕MySQL運維陷阱:基於MyCat的偽分布式架構


分布式數據庫已經進入了全面快速發展階段。這種發展是與時俱進的,與人的需求分不開,因為現在信息時代的高速發展,導致數據量和交易量越來越大。這種現象首先導致的就是存儲瓶頸,因為MySQL數據庫實質上還是一個單機版本的數據庫,而只要是單機,就必然會遇到的一個問題就是存儲問題,因為存儲是硬需求,而CPU和內存如果不夠的話,只是性能不好,並不會直接否定方案或者架構。

 

存儲問題的解決,其實我們每一家公司或者個人,都一直在努力着。解決方案大概有三個方面:

 

1、增大磁盤

 

這種方式應該是最直接、最簡單的方案了,因為磁盤空間不足了,當然加磁盤是手到病除,比如現在是800G,可以增加到2T,這是沒問題的;如果現在已經達到了2T,當然,還是可以增加到5T的盤。但實際上,這個時候可能DBA就要捏把汗了,這么大數據量的MySQL實例,如何運維?如果數據壞了,如何恢復呢?時間成本呢?

 

5T的數據量,已經非常嚇人了,估計在業內各大公司,沒有DBA會希望自己運維的MySQL實例達到這個量級吧?

 

其實我個人認為,這個已經是不能接受的量了,最合適的是保持在1T以下,超過就要想辦法了。

 

當然,數據量不宜達到這個大小的原因,可能會有人考慮到這是性能的問題,其實不然,或者性能問題很小。因為InnoDB采用的是B+樹的存儲方案,小表最壞情況下沒有查到數據是要找3層,也就是3個頁面的IO,而大表需要的是4個頁面的IO,影響不大。

 

2、數據壓縮

 

為了減少數據對磁盤空間的占用,我們通常也會將數據做壓縮處理,通過一個語句即可搞定,是InnoDB原生支持的一種方式。一般情況下,會將數據占用減少到原來的三分之一到一半不等,效果還是足夠明顯的,不過這樣處理之后的數據,在性能上會有所下降,對於響應要求比較高的業務,可能需要謹慎考慮一下。

 

但這種方式還是治標不治本,在數據量繼續增長的情況下,過段時間之后,依然會面臨相同的問題,這種情況下,就不能繼續使用這種方式來實現了。

 

3、數據分片

 

數據分片的解決方案,現在業內用得也很多,這種方案已經超出了MySQL本身,包括HBase、Redis等也都在使用這種方案,應該說這種方案是最具擴展性的,並且可以稱得上是無限擴展。而上面兩種方案,根本談不上擴展性。所以這種方案在業內成為主流,並且這種方案才能稱得上是分布式存儲,具體的實現也層出不窮。當然,存在優秀的分布式解決方案,也存在一些“偽”分布式方案了。

 

一、分布式解決方案需求

 

1、擴展性

 

使用分布式,其實最主要的就是擴展性,如果空間不足了,可以很方便容易的擴展節點個數,並且將數據做新的平衡處理。這個過程要不影響業務使用,對業務透明。

 

2、支持事務

 

分布式數據庫,對於業務本身,使用方面與單機區別不大,也就是對業務透明,因為使用MySQL是支持事務的,那么MySQL變身為分布式之后,事務特性還是不能少的,所以整體上看來,還是要支持分布式事務。

 

3、SQL語句無限制

 

業務需求的多樣性,導致在SQL需求上面都是比較廣泛的,針對業務的透明性,如果某些SQL語句不支持,那這樣導致的問題是,一方面限制了業務程序的功能和性能;另一方面導致業務程序與“分布式數據庫”的捆綁問題。

 

4、性能足夠好

 

使用分布式數據庫,其實基本上是對性能的要求比較低的業務才會這樣選擇,即使是這樣,還是性能越高,越多人才會選擇這樣的分布式數據庫。

 

5、元數據變更透明性

 

元數據變更,在任何數據庫中都是存在的。在單點情況下,改表操作我們有多種友好的方法來實現。但到了分布式環境下,可能這種操作就成為了問題,因為數據的分片導致了元數據的變更需要多點修改,進而很多問題就來了,比如原子性、數據可見性、正確性等等,所以這是最基本的問題。

 

6、底層數據庫的高可用性

 

話說經濟基礎決定上層建築,在分布式數據庫中也是一樣的,如果底層數據庫的不穩定,或者數據復制延遲,亦或出現數據不一致的問題,則上層應用的訪問正確性就沒法保證,所以底層數據庫最基本的就是保證數據一致性(高可用)。

 

二、流行分布式數據庫解決方案

 

1、中間件分庫分表(偽分布式)

 

在MySQL界,一個存在很久的話題,就是“哪個中間件實現的分庫分表方案比較好?”

 

當然對於同一個問題,不同人有不同的理解,也都具有兩面性的特征,有人說好,也有人說不好,我們首先看一下這種方案是如何實現的。

 

 

MyCat的實現架構大概如上圖所示,其實如果只看圖的話,這樣的架構真是完美無缺,自動分片、自動聚合、分布均衡都實現的非常好。

 

但事實並非如此。

 

我們可以通過問答的方式,一步步認清楚這種方式的核心問題:

 

問題1:MyCat如何知道數據分片原理,或者說是如何決定路由路徑的?

 

這個問題,在圖上面是看不出來的。

 

MyCat是如何定義或者決定一條SQL語句的執行方式,或者如何決定去哪里取數據及寫入到哪里的?解決這樣的問題是需要某一個地方來存儲的,它的做法是——schema.xml配置文件,竟然用配置文件來搞定。

 

那這樣問題就多了,修改分庫分表規則之后,如何保證配置與數據同步更新?即使不使用schema.xml配置文件,而是用數據庫存儲,那配置規則的變更與數據節節點中數據的遷移,也是沒辦法保證統一的,勢必會對業務造成影響。

 

問題2:如果需要擴展節點了,並且需要做rebalance,如何來做?

 

很多用戶,基本都是重新准備一套集群,或者先把數據一點點手動導出導入,導到目標節點之后,然后去手動修改schema.xml配置文件,然后做一次reload操作,這樣就實現了重新路由,但這樣同樣會導致上面的結果。

 

並且這個過程,需要處理好多數據,處理完成之后各種檢查,並且占用空間需要兩倍,這樣折騰,一個DBA只要干一次,可能就有辭職的沖動。

 

問題3:全局表是什么東西?

 

MyCat支持一個所謂的全局表,用來解決跨節點數據聚合的問題。實現方法是在每一個分片上面都創建這樣的全局表,它的定義是不怎么修改,查詢比較頻繁表可以定義為全局表,這樣的話在每一個分片節點上,只要用到這個表,就可以實現本地查詢連接等操作。

 

這樣的確是可以解決部分問題,但問題是如果分片多的話(假如分片100個),如何保證數據一致性?這么多節點的XA事務影響是什么?如果出現不一致或者訪問錯誤,引起的問題就是數據結果錯誤,這樣的結果肯定不是業務想要看到的吧?這還不是最關鍵的,一個數據庫集群,搞這么一個特殊處理的東西是何道理?

 

問題4:MyCat究竟做了什么事情?

 

作為一個中間層,本職工作應該是接收客戶端的SQL請求,通過語法分析,根據讀寫原則確定一個集群中一個讀寫節點即可,然后就等着結果集的返回。對於結果集本身,中間層並不需要去關心,只需要將結果集(或者異常)原原本本發回給客戶端即可。

 

而MyCat做的事情遠比這個多,在語法分析之后,再做語義分析,拿到對應數據庫表結構,同時判斷這個表的分發路由規則,再找到語句中的數據及涉及到的列,再決定路由到哪個分片中。如果在分發時路由規則配置錯誤或者程序計算錯誤,會導致整個語句的結果出現不可預知的問題。

 

請問這前半部分,是一個中間層應該做的事情么?竟然還要關心語句中涉及到的表結構、主鍵、數據等信息,這其實都是數據庫要做的事情啊!實則是越俎代庖。

 

再請問,所做的這些事情,能比一個專業數據庫做得更好么?

 

咱再看后半部分,等收到結果集之后,MyCat為了處理一些結果集的聚合計算,需要把各個節點本來已經封裝好的結果集(二進制MySQL協議流數據),解析出來,然后通過需要計算出來(這個計算有可能非常慢,並且不是所有的都可以搞定),計算完成之后,再打包成MySQL協議流數據,傳給客戶端。

 

請問這樣的中間層,做了這么多事情,性能如何保證?而本身這些聚合計算Order By、Group By的處理,本身是數據庫的事情,實則還是越俎代庖。

 

問題5:通過SQL語句的變換,實現分布式是不是有點困難?

 

MyCat這種中間層,代表了宣稱分布式數據庫的一類使用方式,但這種實現方法實際上都是通過在SQL語句上做文章,從客戶端拿到的是SQL語句,給后端數據庫的也是SQL語句,但這兩個SQL語句是經過變換的。

 

當然這種方法也只能這樣,因為后端數據庫只接收SQL語句。試問,一個復雜的SQL語句查詢操作,通過SQL變換或重寫,就能實現對不同分片數據庫的分布式查詢?

 

想想就清楚了,雖然SQL語句通用靈活,但可擴展性或者重寫的邏輯還是有點復雜的吧?當然了,有人可能會說,我們有兜底的啊,大不了把這個語句就改一下庫名表名然后其它保持不變分給每一個節點去執行,這樣總沒問題吧,是的,你說的沒錯。

 

問題6:在同一個事務中要修改不同節點的數據是如何處理的?

 

這個問題就是我們通常所說的分布式事務了。究竟是怎么回事呢?MyCat下面對的是MySQL Server,也就是說MyCat只能用SQL語句與MySQL Server交流,這樣就是局限於MySQL的SQL語句的功能了。

 

那在分布式實現上面,MySQL XA本身有多少人用?MyCat如果實現一個跨節點的數據更新,不用MySQL XA,還能用其它什么?

 

別無他選。本身依賴一個沒有太多人用、並且可能存在很多問題,包括性能、Bug的功能,這樣上層MyCat乃至應用程序的可靠性如何保證?

 

當然基於這些問題,有些方案選擇不用XA,如果某些節點失敗了,選擇忽略不解決,這當然也可以,妥協嘛——不需要底線的。

 

問題7:MyCat后端數據庫的架構是什么,如何保證穩定可靠高可用?

 

這個據某些文章宣傳說,之前可以選擇主從復制,現在可以選擇Galera Cluster,或者也可以選擇更新的MGR。

 

當然不得不說,從前到后,可能確實保證了更好的可靠性,但有一個很大的問題是,Galera的門檻比較高,遇到問題的話,很少人能解決掉。再到MGR,本身還得等,能用還要比較長的時間,這問題還是要回到主從復制,這是老問題了,主從復制的一致性很難保證,MyCat如果通過讀寫分離策略將讀打到從上面,而這個正好有延遲,這樣產生的后果可能是整個應用程序的計算結果是錯誤的。

 

當然可以說有延遲檢查,那問題是,延遲檢查的話,是不是還有一個參數可以配置呢?如果延遲超過100秒的話就去查主庫?

 

沒錯,不過100秒難道就不是延遲了?那可以設置為0,看到的0,你以為真的是0?其實還是主從復制的劣根性。所以問題還是回到了起點,經濟基礎決定上層建築,基礎不好,上層如何是好?

 

問題8:分片多了的情況下,性能是如何保證損失最小的?

 

這個問題,我並不知道MyCat有沒有做過優化,比如10個分片,如果一個語句的執行會涉及到這十個分片,那在每個分片上重寫語句之后,就要分別在這十個分片上執行對應的語句了。

 

執行時是串行,還是並行?串行的話,性能必然會下降10倍以上,所以做得好點的話,就是並行了,但並行的實現方法是,在MyCat這個連接上面,創建10個線程,去處理這十個節點的執行情況。那這樣的連接多了,MyCat產生的對系統的沖擊就非常大了,性能還是不行。

 

當然也可以說,這里做了連接池,沒錯,是可以的,但MyCat是這樣做的么?這樣做了性能又如何呢?如果有一個超時,整個訪問就失敗了。

 

問題9:配置文件或者配置庫出問題,整個集群會出現什么情況?

 

前面已經說了,MyCat用的是schema.xml來配置的分庫分表策略,這是一個配置文件,MyCat本身的高可用,如果配置多套的話,他們的同步問題,是如何解決的?如果沒有同步(或者同步出問題,或者延遲等),某一個MyCat掛了,業務切換到其它的MyCat時,此時的情況就是:故障……故障……

 

因為數據都亂了。

 

有可能造成的問題是,寫入了錯誤的位置,進而導致整個集群的數據被寫壞。感覺比直接被刪了還嚴重。

 

同樣的問題,感覺MyCat可能會優化這點,也許會改為將其集中存儲在某一個數據庫中,這樣集中管理的話就不需要同步了,想法是好的,但這相當於是把雞蛋放在一個籃子里面了,如果這個配置庫出問題了,業務何去何從?

 

問題10:DDL如何進行?

 

這個問題也許是每個人都關心的事情了,MyCat把數據都分而不相關的分片MySQL節點了,這樣很多在單點上的改表策略都不能用了,而DDL又是一個必須要保證每個節點同時完成的事情,那在分布式上面是如何保證的呢?

 

根據我的調研,好像現在使用MyCat的人,都是通過“同一時刻啟動在每一個節點上更新表結構”這樣的方法來做的,當然還得選擇是半夜,當然我個人覺得也是可行的,因為畢竟已經使用了它,而沒有更好的辦法來解決這個問題。

 

當然咱再說后果,如果做不到無縫原子修改,那對業務的影響不是一星半點,可能會有很多SQL會報表不存在的問題。如果一個語句和另一個語句修改完成時間相差比較多的話,兩個相減的時間就是故障時間了。

 

問題11:據我調研,MyCat還實現了自動故障切換的功能,請問這個靠譜么?

 

我們現在討論的是分布式架構方案,而這個問題講的情況是,某一個MyCat發現了后端數據庫連不上了,會自動切換的功能。這就非常明顯了,我們要的是分布式,某“一個”MyCat節點認為的問題就真的是它所認為的嗎?

 

也就是說,一個節點並不能保證判斷的或者看到的現象是真實的,那這種情況下就存在誤切換的情況,而如果其它中間層節點還不知道這個情況,或者未及時收到切換的消息,就出現了多點寫入的問題,挺可怕的。

 

這不是自相矛盾嗎?

 

我們要的是分布式,結果又存在“獨斷”的環節,可靠性又下降了不少。關於分布式監控切換的問題,因為在去哪兒用的mysql-sentinel對Galera Cluster做的監控,我對這點深有感觸,所以不得不在這里講一下。

 

問題12:在MyCat上面備份是如何做的?能做到恢復一個快照嗎?

 

說起備份,做為數據庫使用者,應該沒有一個不清楚,沒有一個人會覺得不重要吧?當然,重要是重要,但這種事情屬於重要不緊急的工作,但沒有是不行的,這個連公司內審這一關都過不了,也許我們每一個人都不會希望能用到它。

 

言歸正傳,這么重要的備份工作,在MyCat上又是什么情況呢?

 

可能了解一些基本原理的人都比較清楚,Xtrabackup、mysqldump等也都是可以用的,但備份完了之后可能心里還是感覺沒底,因為這樣的工具,只能對一個MySQL節點做備份。如果分10個分片(10個MySQL節點)的話,可以通過備份十次即可完成,但需要注意的是,備份了十次產生了十個備份集,而並不是一個備份集,這十個備份集之間是完完全全沒有關系的,此時我可能就提出一個比較極端的問題來:

 

如果哪天(當然我們都不希望有這樣的一天),整個機房掛了,當然假如“幸運”的是,有備份,那在這種情況下,如何恢復一個可用的數據一致及完整的集群快照呢?

 

這個時候可能會有人很快地說,將十個備份集都恢復了啟動了即可。

 

但問題是這十個沒有關系,備份時間又不是同一時刻完成的,同一個表的十個分片,最新數據有的是8點的,有的是9點的,或者有的甚至是昨天的。這樣恢復出來的表,能用么?基於這樣的表產生的查詢結果,靠譜么?可想而知。

 

當然可能也有人會說,我們的數據不需要一致快照,或者更有甚者只需要備份元數據路由表或者配置文件即可,那這樣就沒問題了,如果MyCat只是定位於用來存儲Zabbix監控數據或者日志數據,可以丟失不要的數據、一文不值的數據,那我覺得沒毛病。

 

或許有人還會說,我們的機房不會掛,或者我們的存儲本來就是跨機房的,掛了的話直接切到另外的機房就行了。那此時又有問題了,如果切換的時候,有復制延遲,丟失了部分數據,那整個集群又會出問題。因為只要有一個分片的數據出問題,整個集群就有問題了。

 

或者另一個問題就是,假設你的機房真的不會掛,但我們經常會遇到的需求是,我要取前幾天某時刻的數據,那此時還是需要通過備份然后恢復一個快照,這個時候還有何話可說,你告訴我究竟如何做到?

 

可能還會有人有疑問,他會說我們是邏輯備份啊,這樣備份出來的是整個庫或者表的一致性快照,這不就解決問題了么?

 

我很同意這位同學的看法,說得對極了,是可以很完美地解決一致性問題,但只要熟悉一點點MySQL的人都知道,類似mysqldump這樣的邏輯備份工具,是何其慢?現在都用分布式存儲了,那肯定是數據量非常大,這個時候還在使用這樣的邏輯備份?你是想干哈?即使備份完成了,那有沒有試過邏輯數據的恢復?幾個G的數據要恢復多久,你算過沒有?想想都頭疼,一條不歸路……

 

問題13:如果已經在使用MyCat了,發現它的風險確實太大了,我如何能下掉呢?

 

這個問題非常好,說明你已經在思考做為一個數據負責人,如何保證數據的可靠性和避免風險的問題了。MyCat風險確實高,但如果已經上了“賊船”並且想下掉的話,此時我可能想問一下(做一回事后諸葛亮),上這個架構的時候為什么不多考慮一下呢?公司的數據就是金錢,你這樣想上就上,想下就下,來回折騰,能升值么?萬一數據寫亂了,這個時候可沒有人賠你錢,還不如上雲呢。

 

不過既然上了,那咱就聊聊如何下掉的問題,我目前感覺最靠譜最穩妥的辦法,貌似只有一個,步驟如下:

 

第1步,先停業務,將所有的寫業務都停止(也不用找深夜時間了,因為12小時根本搞不完)。

 

第2步,通過上面所講的mysqldump做邏輯備份,將所有的庫導出來,生成.sql文件。

 

第3步,然后找一個靠譜的MySQL架構(真正的分布式數據庫,或者磁盤足夠大的話可以不采用分布式,采用Share Nothing的方案即可,也許你需要的並不是分布式,只是被忽悠了),將.sql文件導入進去。

 

第4步,再后就將讀業務遷移到新的數據庫架構上面去。

 

第5步,將寫業務也遷移到新的數據庫架構上面去,然后啟動他們,這個時候應該是可以提供正常的數據庫服務了。

 

我們可以注意一下這個過程,從第1步,到第5步,需要多少時間?這個當然是硬時間,是要移動數據的,邏輯備份和恢復都那么慢,我覺得時間的單位可以用天來統計了。

 

這個時候負責人就可以想想,我用MyCat是圖什么啊,業務的免戰牌掛了好幾天,只是為了彌補當年的一個錯誤決定,追悔莫及。

 

當然也許有些人也會有其它辦法,但因為各個分片都是相互獨立的,還是存在上面的所說的在不停止業務的情況下的“一致性快照”的問題。

 

最后我想說的是,對公司的數據,一定要慎之又慎,要時刻保持負責的態度,折騰數據真的不能升值啊。

 

問題14:MyCat的配置復雜嗎?上手容易么?

 

我們只需要看一個圖片就行了。你能想象這是它的配置文件么?看了之后我估計你也沒有任何使用它的欲望了,很多人在使用之后,是這樣評價的:

 

“MyCat這類,碰都不想碰”

 

配置文件如下:

 

 

竟然是一個XML文件,這個產品經理當時是如何想的?后面也沒有想着做個優化?

 

問題15:最后一個問題,現在做分庫分表做得好的有哪些?

 

有哪些?一個都沒有,這是一條不歸路啊。

 

因為說白了,它是一種偽分布式方案,基礎是不好的,上層就做不好,所以永遠是在補各種坑,走得很累,累人累己。

 

現在可以回過頭來想一想,為什么一些很強大知名的公司做的中間件產品,並沒有做這些事情,比如ProxySQL、Maxscale、MySQL Router等,為什么呢?難道他們的技術不好?或者是沒有這樣的需求?

 

我還是覺得,需求是有的,人與人、業務與業務的需求,是一樣的,但解決方法可能就不一樣了,他們可能早就認為,這是一條錯誤的道路,所以就不會去選擇走,而MyCat這種方案,可能就要回過頭來想想未來的路了。

 

2、互聯網處理大規模在線訪問數據的做法

 

解耦思想充斥着互聯網技術棧的方方面面,為什么這樣做?我想應該是大家都不想拖泥帶水,也不想牽一發而動全身罷了。而在MySQL數據庫層面,使用了重量級的中間層之后,你會發現,大一統看起來是很不錯,但這樣牽一發很可能動全身,這其實並不是好事情。

 

MySQL這種數據庫是在互聯網領域興起並被大規模使用的,在比如賬務、訂單、計費等關鍵業務上使用的也不在少數。

 

在大型互聯網公司,MySQL的使用一定是分庫分表的,通過各種垂直切分和水平切分,把一個數據庫變成一堆數據庫,也就是所說的數據庫集群。但是很少看到在使用的MySQL的時候會在上面架設一層重量級的所謂分布式的中間層,這樣導致的就是緊耦合了,與互聯網的高效聯運相違背,互聯網的數據庫集群都應該是物理上離散的,每一個實例可以自由的控制和遷移,也就是所謂的解耦。

 

解耦的好處可以讓你自由處理每一個獨立的實例或者集群,方便根據實際情況應對業務帶來的變數,該升級的升級,該縮容的縮容,為每一個業務或者每一個業務的數據庫定義不同的維護等級,靈活掌握,隨機而變。

 

解耦的好處可以提升數據庫的絕對性能,數據從業務到磁盤,或者從磁盤到業務,經歷的路徑越短,其效率也就越高。很多使用MySQL的做法就是用一個簡單的中間層分發SQL,這樣的中間層功能清晰、結構簡單、靈活高效,一般不會損失太多性能,這就像MySQL出品的MySQL Router、MariaDB出品的Maxscale、Percona的ProxySQL,還有國內極數雲舟的Arkproxy,他們的行為,都為選擇使用中間層去實現數據架構指明了一個方向。

 

解耦的好處可以讓你的數據庫只干數據庫最擅長的事情,它能保證你的數據安全存儲,它能保證你的數據高效存取,它能保證你數據並發處理,它能保證你的數據靈活接入,這還不夠嗎?

 

綜上所述,我們再次確信一個真理,MySQL因簡單而高效,因高效而流行,不要舍本逐末,聽信忽悠,誤入歧途。

 

當然如果不想在業務層做分庫分表來適配MySQL數據庫的架構,而想通過對業務透明的分布式數據庫來提供業務服務的話,我推薦真正意義的分布式數據庫解決方案,它能解決的是強大的存儲擴展能力、分布式運算、對業務讀寫透明以及友好的故障轉移等問題,這是它們的優勢,也是它們的初衷。

 

3、真正意義的分布式解決方案

 

真分布式方案,其實已經不用太多說了,達到上面所述的需求即可。並且目前也有比較成熟的方案,比較有代表性的產品有Google的Spanner&F1、以及國產數據庫SequoiaDB、TiDB等等。

 

對比之下,這種分布式數據庫對業務無侵入,MySQL數據實現了雲存儲特征,100%兼容MySQL,擴展性非常好,天然支持分布式事務、數據節點及路由節點延遲非常小,通過一致性算法來保證了數據的強一致性,如此種種,都是立足於一個正確的基點之上,來建立起高樓大廈,勢必將基於MyCat的偽分布式數據庫解決方案推入無人問津的深淵,直至淘汰與消亡。

 

三、總結

 

使用MyCat的用戶其實還是挺多的,現在在了解業界市場的情況下,我也是比較能理解他們,因為需求有,但真的是沒有解決方案,選擇使用,實則無奈之舉,畢竟他是開源的,罵歸罵,也無怨言,因為免費嘛,有的用還有什么可言語的呢?我也推薦大家去試用一下,只有知道痛了,才會感覺現在有新的方案出現的美好。

 

本文所述的關於MyCat的一系列問題,主要目的是考慮到為了讓業內同學不要繼續采坑,所以做了一些總結,所述內容限於本人目前對MyCat的理解與認識,如果有紕漏或者不足的地方,歡迎指正或者給予補充,感謝。

 

文章來源於 :  DBAplus社群   微信公眾號

文章鏈接:https://mp.weixin.qq.com/s/McWCXGE8JsgHAz1V2liFHw 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM