帶你吃透分散式的精髓!
1953年,埃布·格羅希提出Grosch定律,即計算機效能會隨著成本的平方而增加。1965年,高登·摩爾提出摩爾定律:當價格不變時,積體電路上可容納的元器件的數目,約每隔18-24個月便會增加一倍。
當今,計算機的普及,也讓越來越多的電腦處於閒置狀態,即使在開機狀態下CPU的潛力也遠未被完全利用。而網際網路的出現,使得連線和呼叫閒置計算資源的計算機系統成為了現實。
於是,分散式計算開始普及,分散式難不難?難!所以更需名師指路!下面要介紹的課程,由京東雲高階總監親自授課哦,趕快往下看吧!
本次直播課程由京東雲高階總監郭理靖資料庫基礎入手,從實踐應用出發,深度解析從單機資料庫到分散式資料庫的技術發展與迭代,同時並理論結合實際為大家講述企業選擇資料庫服務的金科玉律以及京東雲針對此方面的應用實踐等乾貨內容。
課程概要
此次課程的分享內容更多關於資料庫服務的演變史,重點講述單機到分散式的變化從何而來以及從單機資料庫如何進行改進才可達成分散式資料庫的服務。
以下是郭理靖老師分享的全部內容,希望給各位開發者帶來更多幫助:
從單機到分散式,資料庫服務的演變史
— 京東雲高階總監 郭理靖—
(建議在Wi-Fi環境下觀看↓)
1
從Redis到MongoDB
從Redis到MongoDB,最初的產生都很簡單
很多時候,一門技術甚至一種產品,最初的產生往往都來源非常簡單的想法,例如2019年,我們看到DB-Engines Ranking中有兩個比較熟悉的身影,MongoDB和Redis。
很有意思的是,MongoDB屬於DocumentDB。如果我們調頭去看DocumentDB-Engines Ranking的話,可以發現MongoDB是排在第一位,而且是以絕對性的優勢“吊打”第二位到第十位(第二名只有56分),整個DB-Engines中,Oracle和MySQL的分數靠得特別近;但是在DocumentDB中,MongoDB是400多分,但第二名可能就只有100多分。
同樣,Redis在K/V的領域,分數也特別靠前,它146分,第三名是MemcacheD(第二名為Amazon DynamoDB,為56分) 只有28.7分。
所以這兩個資料庫在自己的專業領域中都是排名特別靠前的兩個資料庫,而且彼此出現的時間都不算特別長,不到十年:Redis出現的比MongoDB早一些,Redis是2009年,MongoDB差不多也是在2009年左右出現的。
為什麼Redis會出現,並且成為K/VDB排名第一的一個數據庫呢?
其實,在Redis出現之前已經有一個K/V的資料庫叫Memcached,早在2003年釋出,最初用Perl寫了一個版本,最後用C語言重寫了。在Redis沒有出現之前,Memcached一直是K/V資料庫的領頭,為什麼在2009年,當Redis出現時就飛快地代替了Memcached,直至今日,大部分的快取我們都用Redis。 甚至剛入行的同學們根本沒有聽說過還有Memcached這樣的資料庫,這個過程中Redis到底做了什麼事情?
事情比較簡單,從設計理念出發,就是把原先Memcached的儲存結構進行了改變。之前是一個Key對應一個String,然後Redis把String變化成一個可以結構化的Structured storage,也就是說Redis可以支援一些結構化的資料,包括List、sorted set、hashes等 。
如此小的變化為什麼能夠讓它取得這麼大的優勢?關於此還是要回溯下Memcached。
假設我們自己要設計一個快取系統的話,設計目標與Memcached一樣,過程中就需要設計一個Key String的快取系統,那麼在這個快取系統上到底能夠提供哪些服務呢?更進一步來說,當儲存物件是String,針對此我們可以做到哪些操作?
可以想見,在一個程式語言中,以以C++或者Java為例,一個字串可以set一個字串,還可以get一個字串,當然也可以delete一個字串。此外,對於字串我們還可以做一些其他操作,例如append、prepend等,也就是字串的尾巴和頭部加些內容,甚至可以將整個字串替換掉。當然,也可以做insert、erase,還有trim這種操作以及find、substr等。
大家在設計過程中不妨想一想,為什麼在Memcached中不支援insert或find、substr這樣的操作呢?
這其實是一個很有意思的話題。理論上Memcached可以支援這些操作,包括針對Memcached的原始碼進行修改之後,也可以支援這些函式和呼叫,但之所以選擇不支援可能更多還是效率方面的考量。
例如在Memcached中支援substr或者find的操作的過程中,卻浪費了Memcached伺服器的效能。因為find可以把整個字串轉移到本地再做find,substr也是一樣,其實都歸功於效能。
當然Memcached也可以提供更高階的一些操作,例如add或者一些gets操作,還可以做incr/decr,對一個數字進行原子性加減,都可以。如果去研究Memcached整個release history的話,它是2003年開始釋出的一個版本,前期支援的工作是非常有限的,所以後續的高階功能也是慢慢逐漸加進去的。
再看一下Redis,可以支援的資料結構有很多,包括Strings、Lists、Sets、Sorted sets、Hashes、Bit arrays,還有HyperLogLogs、streams,streams是5.0,最新的版本甚至可以支援一些時序性的資料。
縱觀整個迭代歷程,Redis最初的簡單想法就是能不能將Strings的結構和儲存結構,讓其支援的多一些。從這個想法出發,才會逐漸發展成慢慢去支援越來越多的資料結構,支援越來越多操作型別的局面。
以C++為例,一個List操作支援pop/push,也可以支援在List中間去Insert/erase。對於Redis而言,除了常見的操作之外,我看了一下Redis整體的release history,最開始的時候也支援的是一些比較簡單的操作,例如pop/push;隨著時間的發展,支援越來越多的高階功能,都是建立在普通的操作上。
比方說BRPOPLPUSH這個功能,就是從一個List中POP一個數據出來,插入到另外一個List中去,這算是比較高階的功能體現了,但這個也是在使用者發現其需要此種場景之後才去增加的事項。
再來探究下MongoDB。MongoDB的“工作”其實與Redis有點類似,可以認為Redis就是利用K/V結構,將Strings換成了一個類似於JSON的型別,JSON中可以支援的資料結構也非常多。
MongoDB所體現的功能相似度很高。以前在設計資料庫的時候,如果是關係型資料庫,一開始就需要將Schema設計好,然後去做一個DDL操作。當需要增加一列或者減少一列的時候,以上的操作並不是很方便;特別在表單很龐大的情況下,操作時間會很長。
隨著業務的發展,是否可以用一個JSON來代替原型MySQL Schema?以這樣一種簡單的想法出發,如今儘管MySQL或者關係型資料庫還是以Schema為核心,但是MongoDB就以Document,也就是JSON這個格式為核心去構建整個資料庫的功能和生態。
可以看到,MySQL的常見SQL語句在MongoDB中命令長度不太一樣,因為所有的命令都與JSON的格式有關,包括底層的儲存結構也會因為要儲存JSON格式而做出很大變化。
這部分集中想要表達的觀點就是很多資料庫以及技術產品的演進,其實都是有脈絡可尋的,主要就是設定解決問題的目標進而完成底層資料結構的修改,其中底層結構確定之後還會在一定程度上影響產品功能,例如MongoDB在很長一段時間內都不支援事務,不是不想去嘗試支援,而是取決於底層儲存結構的儲存引擎,無法支援事務。
同樣的道理,探究Memcached和Redis的記憶體管理設計,也會發現,Memcached的開發者或者說社群,也想去支援像Redis一樣的功能,但事實上由於底層的儲存結構註定無法提供此類服務。
2
分散式從何而來?
為什麼會有分散式?主要還是由於處在資訊爆炸的時代,業務量逐漸龐大導致單機資料庫並不能更好滿足需求,自然要尋找一些可行的解決方案。
這裡的解決方案可以分為兩種,一類相當於表層的解決方案,操作起來比較簡單,其中涉及客戶端的方案以及統一代理的方案等,例如proxy的方案。
相比之下,底層的方案可以分為三類。第一類是分散式塊儲存方案,第二類是計算與儲存分離方案,第三類就是要另起爐灶了。
首先客戶端方案,可以以友商開源的專案稱為TDDL為代表,方案思路較為清晰。 如果我們自身需要做一個分散式系統的話,將分散式解決方案放入客戶端內,最重要的就是“告訴”客戶端SQL語句應該連結到背後哪個資料庫,畢竟不同的資料儲存在不同的機器當中。對於客戶端的方案,比較重要的就是與後端的一些連線,以及如何解析這個SQL語句。
第二種方案就是Proxy方案。 Proxy方案相對客戶端方案而言,開發難度稍微高一些,但思路上還是非常一致的。舉例說明,一張使用者表,使用者表的元件是ID,我們對ID的分散式key進行分佈,查詢具體某一個使用者ID的時候其實就有一個Proxy,如果說查詢這個使用者ID為0,進而就知道0是存在於後臺的哪一臺MySQL。
所以對於Proxy而言,非常重要的一點還是需要去解析具體的SQL語句,這個過程中必須需要有一個自己的路由,就可以完成識別。
客戶端的方案與Proxy方案的區別在哪裡? 區別在於客戶端的方案開發起來相對比較簡單一點,在JDBC中或者要求客戶端呼叫時,客戶端可以不解析SQL語句,完成導向很容易。
對於Proxy方案,它需要相容原有的MySQL協議,怎麼建立MySQL連線,怎麼與後端保持連線,這個難度比較大。但相對而言,Proxy方案的限制也比較多,不管是客戶端的表層方案,還是Proxy的表層方案,它們對SQL的使用要求都是比較高的,例如一些join是比較難支援的,而且要與業務方達成一致。
此外,無論是客戶端方案還是Proxy方案,整體架構還是比較類似的。例如Proxy方案,它會涉及前端如何與客戶端進行連線以及後端的Backend connection,還要與後端真正提供MySQL服務的保持連線,這是兩個連線的管理。
經過了解,整個Proxy一般的設計都會採取無狀態,因為路由資訊都是儲存在Proxy本機的;但路由方面肯定有一個相對的路由管理中心去分發和更改控制。業界大部分Proxy設計,大家都會發現,Proxy代理的方案其架構設計非常相像,區別在於工程質量不同而已。
另外,對於Proxy方案的缺點就是怎麼去做一個分散式事務,沒辦法保證次序。通常在一個分散式的情況下,其實很難保證每個節點上的事務執行是按照我們想像中的次序去做。
講完表層的解決方案之後,我們還需要講講比較深層次的底層解決方案。 從表層出發,不管是客戶端方案還是Proxy方案,都並沒有去改變底層MySQL的整體協議,也沒有改變資料庫原生服務,可以認為根本就沒有讓MySQL底層程式碼發生變動。
如今可知曉的底層解決方案主要有三個,第一個方案是塊儲存方案,包括SAN解決方案,涉及雲端就是雲硬碟解決方案,都是同一型別的。
但如果真正要做一個數據庫的解決方案,目前的主流思路還是計算與儲存分離,為什麼會出現計算與儲存分離呢? 主要原因有以下幾點:現在的網路延時一直在下降,頻寬一直在增長,從我個人的工作經驗來看,未來可能還有更大的網路頻寬出現;但與此同時,磁碟IO的吞吐量並沒有增長得像網路這麼快。
此外,儲存的虛擬化有利於成本下降,分散式儲存有利於提高IOPS。如果在一個機器上做Raid的話,它的效能會比單個硬碟要好很多;如果採用分散式系統寫入,它的IOPS其實會更高。
目前業界比較有名的幾個計算與儲存分離的解決方案,最著名的就是亞馬遜的Aurora。
Aurora為什麼選擇計算儲存分離?關於這一點,還需要探究當時亞馬遜做RDS的解決方案如何。亞馬遜RDS,就是它們的Realtional Database Service,整體資料存在local disk/EBS上面。
我們可以看到,整個IO的寫入鏈條是比較長的,要把資料落盤,binlog落盤,redo log落盤,而且整個binlog兩邊要同步,最後還要把EBS的資料適當地備份到雲端儲存中去。(這個只是備份,與實時寫入無關)。
由於鏈路比較長,而且包括整個EBS的實現中,EBS就是個分散式的快儲存,本質上也是多副本的。在多副本的情況下,EBS在遠端也要做整個資料的同步,所以Aurora的設計目標就是思考能不能把儲存與計算做一些相應的分離。出發點就是資料庫儲存引擎能不能與分散式塊儲存融合在一塊,融合成一個新的儲存引擎。
另外一個方案是F1/Spanner的方案,思路又是什麼呢?
做一個分散式系統,如果去相容MySQL比較麻煩的話,那是不是可以另起爐灶,做一個新的分散式系統。
它的思路很簡單,就是重新去改寫一些SQL,所以像F1/Spanner並不相容MySQL的一些協議時,就會引入新的分散式事務管理,把SQL都拆解成K/V的一些操作結構,對這種方案而言,SQL的相容性是個長期耗時而且是無限接近的一個過程,主要需相容已有的生態會比較費力。但如果是一個新業務,用這種分散式方案就沒有問題;如果是個舊業務,有自己成熟的SQL,想用它就比較困難了。
可以看到對一個MySQL服務而言,其實有兩部分組成,一部分是Server,一部分Storage。Storage標準的架構是redo log加個data,這是InnoDB的一個結構,如今InnoDB已經成為MySQL的一個標準,大家都是按照這種方式去做的。
關於主從同步,是用binlog複製的方式,把binlog複製到Slave這邊,Slave對binlog重放,然後Slave就有完整資料,這是傳統的一個數據庫組成模式。
對於MySQL而言,它的資料流向會是什麼樣子的? 第一步,如果針對一個事務或者一個SQL語句,它會寫很多redo log。第二步,會寫到binlog中,binlog以後會做半同步,會同步到Slave中,返回一個資訊,這時候可以進行一個整體的commit。
對於整個資料流向的一個示意圖,主從之間用了整體的binlog複製方式去做。如果想做一個分散式系統的話,而且出發點是不能夠將這些一樣的資料放在同一個分散式系統中,需要做哪些事情?
我們發現,如果計算和儲存分離之後,把所有的儲存都放在一個分散式儲存系統中去,master與slave讀的是同一個資料,其實就不需要binlog了,這個是比較容易理解的。binlog用來傳輸具體的資料,因為資料都放在一起。
3
計算和儲存分離的優點
在於分散式儲存的儲存空間會相對大一些;另外一點,如果說要增加一個新的slave,以前在MySQL的主從複製中增加一個新的slave,通常怎麼做?
要麼就新建一個空白的slave,慢慢從組合開始同步資料,總而言之就是利用binlog同步資料;但如果整個資料量比較大的話,建立一個新的從時間會非常長,或者說根據備份去重建一個新的從,進而拷貝資料庫備份。在這個基礎上再去追新日誌,無論如何增加一個節點,時間應該還是要以分鐘計,至少以10分鐘為單位。
但在計算與儲存分離之後,新建一個slave時間就非常快了,而且備份資料的時候會快很多。因為針對傳統主從系統做備份,其實都要去做一個檔案系統的備份。做檔案系統快照也行,用mysql dump也行,需要把本地檔案傳到雲端儲存;在分散式儲存系統中,可以把這個任務轉移給底層系統去做,當然資料的強一致還要靠底層儲存去保證。
如果把計算、儲存分離之後,整個高可用切換會是什麼樣子的? 對於以前的MySQL而言,一個主從切換其實比較簡單,因為主跟從是兩個獨立的儲存和計算,之間沒有關聯關係,主切換到從,最多就是binlog還沒有回放完;但對於整個計算儲存分離之後,它的變化還是有一些的。
例如第一個變化,我們可以看到對於傳統資料庫而言,它的Redo日誌是一個迴圈的檔案系統,可以是三個Redo日誌迴圈使用;如果在一個儲存分離,計算分離的環境,它的Redo日誌基本會設計成按編號去排序的情況。
等主從切換之後,log buffer和buffer pool,也許需要一點時間去重建它的兩個buffer pool。因為在傳統意義上,傳統的MySQL主從切換都需要去根據日誌稍微重建一下buffer pool。
對於備份而言,基本上變化也比較大,整個備份會基於底層的塊儲存:一部分可以去備份整個page頁的資料;另外一部分,需要去做Redo日誌的增量備份,這樣很快能完成一個數據庫的備份。
其實在雲端去做一個數據庫的備份會比自己搭建兩臺物理機去做備份更快,為什麼?
因為在雲端分散式系統中,做備份的時候不是一臺機器在備份,因為儲存在不同的機器上。 對於一個新建的slave而言,如果我們在雲端計算、儲存分離的情況下去新建一個slave的話,新建slave的速度也會比傳統的方式快非常多,因為整個資料塊是已經存在了,直接去讀就行,不需要重新再複製一份。
但是這種情況也帶來不少問題。 因為底層的檔案系統其備份數是有限的,副本數也是有限的,深層次的原因是因為底層的分散式檔案系統的IOPS是有限的,對於一個主從關係,像傳統模式下的MySQL,其實並沒有這種限制。
最後總結一下這幾個方案的優缺點:
比如客戶端方案,它的優點是可以接多種資料來源,只要資料庫是相容JDBC的,都可以去對接,而且效能上比較好。但提高效能的同時也帶來另外一個問題,連線數可能會比較多,因為客戶端非常多,每個客戶端都與MySQL進行連線的話,MySQL連線會特別多。
缺點也非常明顯,如果公司中只以Java為主,那沒問題,開發一個jar包,大家用起來會非常熟悉;如果說一個公司用Python、C++,還用Go,每個語言都要寫一個客戶端,其實是非常痛苦的。另外客戶端釋出了,SDK釋出之後升級起來也非常麻煩。
所以絕大部分的廠商會採用Proxy的方案,因為Proxy的方案容易管理,升級也比較容易,而且語法基本相容,不存在多語言SDK的問題。相容了MySQL的一些語法之後,傳統的MySQL客戶端,各種語言的SDK都能用,所有MySQL第三方開發的SDK也都能用,缺點在於不支援事務,或者對事務的支援是有限的。
對於計算與存理分離方案而言,它的優點非常明顯且價效比特別高,為什麼?
雲端購買雲資料庫的時候,很多時候效能與購買有關係。例如買個1C2G10GB的小型資料庫,OPS可能只有幾百上千;但對於真正的計算與儲存分離的方案而言,開始購買的型別可能是比較小的,購買的規格可能也比較小,但是可以達到很高的IOPS效能,資料庫效能並不會受限於你購買的規格。
關於缺點,還是整體的儲存空間有限,可能最大隻能支援64T或者128T,因為每個資料庫的分散式儲存中其副本數是有限的,只讀節點可能受限於,只能有15個或者14個,但這個都不要緊。我相信對於絕大多數的使用者而言,這個還是足夠用的。另外一個缺點是開發難度,但這個缺點只是開發廠商的痛點,與使用者沒有關係。
對於另起爐灶,像Spanner/TiDB這種資料庫方案,它的可擴充套件性就比較高。因為對於像Aurora這種計算與儲存分離的資料庫而言儲存空間畢竟是有限的,但對這種資料庫,它的儲存空間可以被認為是無限擴充套件的,可以支援一個上P的資料庫也沒問題。
依舊談談缺點。就是很難去相容現有的一些SQL語法,是一個比較大的挑戰。例如TiDB是國產比較優秀的資料庫了,也號稱對MySQL的語法相容是比較完美的,但事實上還是很多語句是沒法做到相容的,不是不想,是因為做起來特別難!因為底層的資料結構決定了一些功能,也決定了要去相容一些SQL語句其代價是非常大的。
以上為公開課的所有內容
關注京東雲開發者社群,回覆“PPT0424”獲取課程PPT。
課程問答
Q
為什麼雲端儲存有容量限制?技術上的根本原因是什麼?
A
理論上講我們做分散式儲存的時候,既然講它是個分散式儲存,為什麼它還有空間上的限制?包括我們做快儲存,如果大家用過雲都會用像亞馬遜的EBS,包括京東雲的雲硬碟盤,這幾個問題的本質是一樣的,為什麼快儲存和計算與儲存分離的資料庫它的空間都是有容量限制的?我們為什麼沒法去申請一個無限大的雲硬碟?這個問題可以轉化成另外一個問題,為什麼我們在雲廠商裡面沒法去申請一個超大空間的雲硬碟?我們都沒有看到過哪個廠商提供10個PB,甚至說100PB的雲硬碟,這是為什麼?這裡面還是要回到我最開始講的,就是說你的功能設計目標和你底層儲存結構決定了你的產品功能,決定了你產品的限制。每一家廠商的底層實現的原理都不太一樣,但是結構都還是比較相同的。如果說我們要提供一個非常大的儲存空間的話,它的meta資訊管理會受一個很大的限制。同時,為什麼不會提供超大規模的雲硬碟或者說資料庫?也受限於你本機的網路頻寬也是有限的。 舉個例子,給你提供10PB大小的資料庫或者給你提供10PB的雲硬碟,理論上是可以這麼做,但是你往裡面寫的時候,你寫的IO還是受限於你本機網路的頻寬。同時對整個雲硬碟後端或者資料庫後端快資訊、TiDB資訊的儲存也會帶來新的挑戰。 所以提供10TB的雲硬碟是比較容易的,我是說大家為什麼不提供10PB的雲硬碟,沒有一家廠商提供這麼大的雲硬碟,不是說技術上不可能,只是說這個產品功能上講,哪怕給你提供了這麼大的雲硬碟或者說資料庫,你在單機使用上也發揮不出這麼大容量的優勢,主要是這個原因。
Q
京東有專門資料庫團隊針對相容MySQL的分散式儲存引擎麼?
A
有,之前是這樣的,京東之前的MySQL分散式解決方案,我們採用的也是用Proxy的方案,為什麼會選擇用Proxy的方案?原因有以下幾點:第一點,Proxy方案開發起來比重新改寫引擎還是要相對容易一些的。第二點,你在一個公司內部去推一個分散式方案,業務部門還是比較願意配合的,因為他碰到了儲存空間的問題,他需要有團隊去解決這個問題。 為什麼我們現在開始要做相容MySQL的分散式儲存引擎?是因為我們在雲端給使用者提供一個想比單機版效能更好,空間更大的資料庫服務的時候,我們必須要考慮到使用者的使用場景,使用者現有的架構,使用者的使用習慣。如果說我們要讓使用者來用我們這個Proxy的方案,我們的Proxy方案在京東雲上叫DRDS服務,如果讓使用者來用我們DRDS服務的話,其實要針對他自己的業務進行一些分庫分表的操作,要限制他的SQL語句,對使用者而言他的改造量是比較大的。而且很多時候,對於一些複雜業務而言,它並不具備有這樣的能力去改造它的業務。所以對於使用者而言,我們還是希望能夠提供一個性能也足夠好,空間也相對比較大的,比如說空間也能滿足它的要求的,又不需要它進行任何程式碼更改的資料庫服務,所以我們也會做針對相容MySQL的分散式儲存引擎做開發。
Q
雲端儲存有沒有分庫分表,如果有是怎麼做的?
A
雲端儲存跟資料庫還是兩個完全不一樣的東西,我理解你想要問的是雲端儲存去存它的 meta 資訊 的時候有沒有用到分庫分表,我覺得你應該是問這個意思。絕大部分的雲端儲存肯定是要用分散式的儲存系統或者 K/V ,不管是 K/V 也好,還是 MySQL 也好,它肯定需要做分散式 TiDB 資訊的儲存。因此我們可以看到,它對應的雲端儲存的儲存方式是一個檔名對應它相應的資料內容,我們可以理解成它是一個超大規模 K/V 的持久化程度結構,只是它的 value 可以變成非常大,可以從一個 KB 到 10 個 T 都行,這個就看你的檔案大小了。檔案怎麼儲存,放在哪些機器上?這其實算一個 TiDB 資訊,這個資訊是海量的,對於所有的雲端儲存而言它肯定要用到分散式,至少用到分散式 K/V 的儲存。分散式 K/V 儲存涉及到的內容跟你做一個分散式資料庫的思路和方法還是非常類似的。
Q
分散式快取和分散式資料庫關係是怎樣的?
A
這兩個分散式的難度不一樣,它解決問題的難度不一樣。分散式快取系統,比如說我們以 Codis 為例, Codis 做的樣子還是會很像我們剛才講的資料庫的 Proxy 的方案,它長的幾乎一模一樣,只是一個支援 MySQL 的語法,一個支援 Redis 的語法而已。分散式快取它面臨的挑戰比較小,因為它不需要支援事務,而且分散式快取系統支援的語法裡面比較簡單,它並沒有複雜的 SQL 、 join 查詢這種東西,它的語句支援起來比較容易。對於一個數據庫而言,你如果真正想做到一個分散式資料庫,而且相容大部分的 SQL 語法的話,你要做分散式事務,而且要支援各種複雜的 SQL ,子查詢,挑戰還是非常大的,這兩者的難度完全不一樣,可以認為分散式資料庫比分散式快取要做的難度至少乘以 10。
·END·