摘要:本文由紅鳳凰粉鳳凰粉紅鳳凰隊的成員主筆,他們的項目在本屆中獲得了二等獎。用戶在平臺上進(jìn)行第一章部署的學(xué)習(xí),了解到可以通過進(jìn)行部署。收到事件后,更新。由于位置是由屬性給出的,因此為其加上,即可實
本文由紅鳳凰粉鳳凰粉紅鳳凰隊的成員主筆,他們的項目 TiDB Lab?在本屆 TiDB Hackathon 2018 中獲得了二等獎。TiDB Lab 為 TiDB 培訓(xùn)體系增加了一個可以動態(tài)觀測 TiDB / TiKV / PD 細(xì)節(jié)的動畫教學(xué) Lab,讓用戶可以一邊進(jìn)行真實操作一邊觀察組件之間的變化,例如 SQL 的解析,Region 的變更等等,從而生動地理解 TiDB 的工作原理。項目簡介 簡介
TiDB Lab,全稱 TiDB Laboratory,是一個集 TiDB 集群狀態(tài)的在線實時可視化與交互式教學(xué)的平臺。用戶可以一邊對 TiDB 集群各個組件 TiKV、TiDB、PD 進(jìn)行各種操作,包括上下線、啟動關(guān)閉、遷移數(shù)據(jù)、插入查詢數(shù)據(jù)等,一邊在 TiDB Lab 上以動畫形式觀察操作對集群的影響,例如數(shù)據(jù)是怎么流動的,Region 副本在什么情況下發(fā)生了變更等等。通過 TiDB Lab 這種對操作進(jìn)行可視化反饋的交互模式,用戶可以快速且生動地理解 TiDB 內(nèi)部原理。
功能實時動態(tài)展示 TiDB、TiKV 節(jié)點的新增、啟動與關(guān)閉。
實時動態(tài)展示 TiDB 收到 SQL 后,物理算子將具體請求發(fā)送給某些 TiKV Region Leader 并獲取數(shù)據(jù)的過程。
實時動態(tài)展示各個 TiKV 實例上 Region 副本狀態(tài)的變化,例如新增、刪除、分裂。
實時動態(tài)展示各個 TiKV 實例上 Region 副本內(nèi)的數(shù)據(jù)量情況。
瀏覽集群事件歷史(事件指上述四條功能所展示的各項內(nèi)容)并查看事件的詳細(xì)情況,包括事件的具體數(shù)據(jù)內(nèi)容、SQL Plan 等等。
按 TiDB、TiKV 或 Region 過濾事件歷史。
對事件歷史進(jìn)行時間穿梭:回到任意事件發(fā)生時刻重新觀察當(dāng)時的集群狀態(tài),或按事件單步重放觀察集群狀態(tài)的變化。
在線獲取常用運維操作的操作指南。
愿景我們其實為 TiDB Lab 規(guī)劃了更大的愿景,但由于 Hackathon 時間關(guān)系,還來不及實現(xiàn)。我們希望能實現(xiàn) TiDB Lab + TiDB 生態(tài)組件的沙盒,從而在 TiDB Lab 在線平臺上直接提供命令執(zhí)行與 SQL 執(zhí)行功能。這樣用戶無需離開平臺,無需自行準(zhǔn)備機(jī)器下載部署,就可以直接在平臺上根據(jù)提供的操作指南進(jìn)行各類操作,并能觀察操作帶來的具體影響,形成操作與反饋的閉環(huán),真正地實現(xiàn)零門檻瀏覽器在線教學(xué)。我們期望平臺能提供用戶以下的操作流程:
1. 用戶獲得一個 TiDB Lab 賬戶并登錄(考慮到沙盒是占用實際資源的,需要通過賬戶許可來限制避免資源快速耗盡)。
2. 用戶在 TiDB Lab 上獲得若干虛擬機(jī)器的訪問權(quán)限,每個機(jī)器處于同一內(nèi)網(wǎng)并具有獨立 IP。這些虛擬機(jī)器的實際實現(xiàn)是資源受限的虛擬機(jī)或沙盒,因為作為教學(xué)實驗不需要占用很多資源。
例如:平臺為用戶自動分配了 5 個 IP 獨立的沙盒的訪問權(quán)限,地址為 192.168.0.1 ~ 192.168.0.5。
3. 用戶在平臺上進(jìn)行第零章「架構(gòu)原理」的學(xué)習(xí)。平臺提供了一個默認(rèn)的拓?fù)洳渴穑脩艨梢栽谄脚_提供的在線 SQL Shell 中進(jìn)行數(shù)據(jù)的插入、刪除、更新等操作。用戶通過平臺觀察到 SQL 是如何對應(yīng)到 TiKV 存儲節(jié)點上的,以及數(shù)據(jù)是怎么切分到不同 Region 的等等。
4. 用戶在平臺上進(jìn)行第一章「TiDB 部署」的學(xué)習(xí),了解到可以通過 ansible 進(jìn)行部署。教學(xué)樣例是一個典型的 TiDB + TiKV 三副本部署。對于這個教學(xué)樣例,平臺告知用戶 inventory.ini 具體內(nèi)容應(yīng)當(dāng)寫成什么樣子。用戶可以在平臺提供的在線 Terminal 上修改 inventory 文件,并執(zhí)行部署與集群啟動命令。部署和啟動均能在平臺上實時反饋可視化。
5. 用戶繼續(xù)進(jìn)行后續(xù)章節(jié)學(xué)習(xí),例如「TiDB 單一服務(wù)啟動與關(guān)閉」。用戶在可視化界面上點擊某個剛才已經(jīng)部署出來的節(jié)點,可以了解啟動或關(guān)閉單個 TiDB 的命令。用戶可以在平臺提供的在線 Terminal 上執(zhí)行這些命令,嘗試啟動或關(guān)閉單一 TiDB。
6. 用戶繼續(xù)學(xué)習(xí)基礎(chǔ)運維操作,例如「TiKV 擴(kuò)容」。平臺告知 inventory.ini 應(yīng)當(dāng)如何進(jìn)行修改,用戶可以根據(jù)指南在在線 Terminal 上進(jìn)行實踐,并通過可視化界面觀察擴(kuò)容的過程,例如其他節(jié)點上的副本被逐漸搬遷到新節(jié)點上。
前期準(zhǔn)備 團(tuán)隊我們團(tuán)隊有三個人,是一個 PingCAP 同學(xué)與 TiDB 社區(qū)小伙伴錢同學(xué)的混合組隊,其中 PingCAP 成員分別來自 TiKV 組與 OLAP 組。我們本著搞事情的想法,團(tuán)隊取名叫「紅鳳凰粉鳳凰粉紅鳳凰」,想圍觀主持人念團(tuán)隊名稱(然而機(jī)智的主持人小姐姐讓我們自報團(tuán)隊名稱)。
原計劃:干掉 gRPC鑒于從報名開始直到 Hackathon 正式開始前幾小時,我們都在為原計劃做準(zhǔn)備,因此值得詳細(xì)說一下…
我們一開始規(guī)劃的 Hackathon 項目是換掉 TiKV、TiDB 之間的 RPC 框架 gRPC,原因有幾個:
一是發(fā)現(xiàn) TiKV、TiDB 中 gRPC 經(jīng)常占用了大量 CPU,尤其是在請求較多但很簡單的 benchmark 場景中經(jīng)常比 Coprocessor 這塊兒還高,這在客戶機(jī)器 CPU 資源比較少的情況下是性能瓶頸;
二是發(fā)現(xiàn) gRPC 性能一般,在各類常用 RPC 框架的性能測試中 gRPC 經(jīng)常是墊底水平;
三是 gRPC 主要設(shè)計用于用戶產(chǎn)品與 Google 服務(wù)進(jìn)行通訊,因而考慮到了包括負(fù)載均衡友好、流量控制等方面,但對 TiKV 與 TiDB 這類內(nèi)部通訊來說這些都是用不上的功能,為此犧牲的性能是無謂的開銷;
另外近期 TiKV 內(nèi)部有一個實驗是將多個 RPC 請求 batch 到一起再發(fā)送(當(dāng)然處理時候再拆開一個一個執(zhí)行原來的 handler),性能可以瞬間提高一倍以上,這也從側(cè)面說明了 gRPC 框架自身開銷很大,因為用戶側(cè)請求總量是一致的,處理模式也是一致的,唯一的區(qū)別就是 RPC 框架批量發(fā)送或一條一條發(fā)送。
我們早在幾周前就開始寫簡單 Echo Server 進(jìn)行可行性驗證和性能測試,是以下三個方面的正交:
1. 協(xié)議:CapnProto RPC、brpc over gRPC、裸寫 echo。
2. 服務(wù)端:Rust、C++,對應(yīng)用于 TiKV。
3. 客戶端:Golang,對應(yīng)用于 TiDB。
其中 TiKV 側(cè)調(diào)研了 Rust 和 C++ 的服務(wù)端實現(xiàn),原因是 Rust 可以通過 binding 方式調(diào)用 C++ 服務(wù)端。而 TiDB 側(cè)客戶端實現(xiàn)不包含 C++ 的原因是 Golang 進(jìn)行 C / C++ FFI 性能很差,因此可以直接放棄 C/C++ 包裝一層 binding 用于 TiDB 的想法。最后測試下來,有以下結(jié)果:
CapnProto:序列化性能很高,但其 RPC 性能沒有很突出。最重要的是,CapnProto 的 Golang Client 實現(xiàn)有 bug,并不能穩(wěn)定地與 Rust 或 C++ 的 Server 進(jìn)行 RPC 交互。作者回復(fù)說這是一個已知缺陷,涉及重構(gòu)。這對于 Hackathon 來說是一個致命的問題,我們并沒有充足的時間解決這個問題,直接導(dǎo)致我們放棄這個方案。
brpc over gRPC:可以實現(xiàn)使用 brpc C++ 客戶端 & gRPC Golang 服務(wù)端配合(注:brpc 沒有 Golang 的實現(xiàn))。但這個方案本質(zhì)只是替換服務(wù)端的實現(xiàn),并沒有替換協(xié)議,并不徹底,我們不是特別喜歡。另外在這個換湯不換藥的方案下,測試下來性能的提升有限,且隨著 payload 越大會越小。我們最終覺得作為一個 Hackathon 項目如果僅有有限的性能提升(雖然可以在展示的時候掩蓋缺陷只展示優(yōu)點),那么意義不是很大,最終無法用于產(chǎn)品,因而放棄。
裸寫:我們?nèi)齻€成員都不是這方面的老司機(jī),裸寫大概是寫不完的。。
新計劃:做一個用于培訓(xùn)的可視化在 Hackathon 開始的前一個晚上,我們決定推翻重來,于是 brain storm 了幾個想法,最后覺得做一個用于教學(xué)的可視化比較可行,并且具有比較大的實際意義。另外,這個新項目「集群可視化」相比原項目「換 RPC」來說更適合 Hackathon,主要在于:
1. 具有圖形化界面,容易拿獎可以直觀地展現(xiàn)成果。
2. 并不是一個「非零即一」的任務(wù)。新項目有很多子功能,可以逐一進(jìn)行實現(xiàn),很穩(wěn)妥,且不像老項目那樣只有換完才知道效果。
我們繼續(xù)在這個「可視化」的想法上進(jìn)行了進(jìn)一步的思考,想到如果可以做成在線教學(xué)的模式,則可以進(jìn)一步擴(kuò)展其項目意義,形成一個完整的在線教學(xué)體系,因此最終決定了項目的 scope。
具體實現(xiàn)在 TiKV、TiDB 與 PD 中各個關(guān)鍵路徑上將發(fā)生的具體「事件」記錄下來,并在前端進(jìn)行一一可視化。事件
我們將 TiDB Lab 進(jìn)行可視化所需要的信號稱為「事件」,并規(guī)劃了以下「事件」:
Ansible 事件:Ansible 部署 TiDB
Ansible 事件:Ansible 部署 TiKV
TiDB 事件:TiDB 啟動
TiDB 事件:TiDB 關(guān)閉
TiDB 事件:TiDB 收到一條 SQL
TiKV 事件:TiKV 啟動
TiKV 事件:TiKV 關(guān)閉
TiKV 事件:TiKV 收到一條 KvGet 請求
TiKV 事件:TiKV 收到一條 PreWrite / Commit 請求
TiKV 事件:TiKV 收到一條 Coprocessor 請求
TiKV 事件:TiKV Region Peer 創(chuàng)建
TiKV 事件:TiKV Region Peer 刪除
TiKV 事件:TiKV Region 分裂
TiKV 事件:TiKV Region Snapshot 復(fù)制
TiKV 事件:TiKV Region 數(shù)據(jù)量發(fā)生顯著變化
最后,由于時間關(guān)系、技術(shù)難度和可視化需要,實際實現(xiàn)的是以下事件:
TiDB 事件:TiDB 啟動,若首次啟動認(rèn)為是新部署
TiDB 事件:TiDB 關(guān)閉
TiDB 事件:TiDB 收到 SQL 并發(fā)起 KvGet 讀請求
TiDB 事件:TiDB 收到 SQL 并發(fā)起 PreWrite / Commit 寫入請求
TiDB 事件:TiDB 收到 SQL 并發(fā)起 Coprocessor 讀請求
TiKV 事件:TiKV 啟動,若首次啟動認(rèn)為是新部署
TiKV 事件:TiKV 關(guān)閉
PD 事件:TiKV Region Peer 創(chuàng)建(通過 Region 心跳實現(xiàn))
PD 事件:TiKV Region Peer 刪除(通過 Region 心跳實現(xiàn))
PD 事件:TiKV Region 分裂(通過 Region 心跳實現(xiàn))
PD 事件:TiKV Region 數(shù)據(jù)量發(fā)生顯著變化(通過 Region 心跳實現(xiàn))
可視化可視化部分由前端(lab-frontend)和事件收集服務(wù)(lab-gateway)組成。
事件收集服務(wù)是一個簡單的 HTTP Server,各個組件通過 HTTP Post 方式告知事件,事件收集服務(wù)將其通過 WebSocket 協(xié)議實時發(fā)送給前端。事件收集服務(wù)非常簡單,使用的是 Node.js 開發(fā),基于 ExpressJs 啟動 HTTP Server 并基于 SocketIO 實現(xiàn)與瀏覽器的實時通訊。ExpressJs 收到事件 JSON 后將其通過 SocketIO 進(jìn)行廣播,總代碼僅僅十幾行。
可視化前端采用 Vue 實現(xiàn),動畫使用 animejs 和 CSS3。
通過模板實現(xiàn)的可視化
一部分事件通過「由事件更新集群狀態(tài)數(shù)據(jù) – 由集群狀態(tài)通過 Vue 渲染模板」進(jìn)行可視化。
這類可視化是最簡單的,以 TiDB 啟動與否為例,TiDB 的啟動與否在界面上呈現(xiàn)為一個標(biāo)簽顯示為「Started」或「Stopped」,那么就是一個傳統(tǒng)的 Vue MVVM 流程:
1. 數(shù)據(jù)變量 instances.x.online 代表 TiDB x 是否已啟動。
2. 收到 TiDB Started 事件后,更新 instances.x.online = true 。
3. 收到 TiDB Stopped 事件后,更新 instances.x.online = false 。
4. 前端模板上,根據(jù) instances.x.online 渲染成 Started 或 Stopped 對應(yīng)的界面。
這類可視化的動畫采用的是 CSS3 動畫。由于 Region Peer 位置是由 left, top CSS 屬性給出的,因此為其加上 transition,即可實現(xiàn) Region Peer 在屏幕上顯示的位置改變的動畫。位置改變會主要發(fā)生在分裂時,分裂時 Region 列表中按順序會新增一個,那么后面各個 Region 都要向后移動(或換到下一行等)。
最后,使用 Vue Group Transition 功能,即可為 Region Peer 的新增與刪除也加入動畫效果。
通過動畫實現(xiàn)的可視化
另一部分事件并不反應(yīng)為一個持久化 DOM 的變化,例如 TiDB 收到 SQL 并發(fā)請求到某個具體 TiKV 上 Region peer 的事件,在前端展示為一個 TiDB 節(jié)點到 TiKV Region Peer 的過渡動畫。動畫開始前和動畫結(jié)束后,DOM 沒有什么變化,動畫是一個臨時的可視元素。這類動畫通過 animejs 實現(xiàn)。
時間穿梭
時間穿梭是一個在目前前端框架中提供的很時髦的功能,我們準(zhǔn)備借鑒一波。主要包括:1. 回退到任意一個歷史事件發(fā)生的時刻展示集群的狀態(tài);2. 從當(dāng)前事件開始往后進(jìn)行單步可視化重現(xiàn)。
時間穿梭的本質(zhì)是需要實現(xiàn)兩個基礎(chǔ)操作:
1. 對于單一事件實現(xiàn)正向執(zhí)行,即事件發(fā)生后,更新對應(yīng)集群數(shù)據(jù)信息(如果采用「通過模板實現(xiàn)的可視化」),或創(chuàng)建臨時動畫 DOM(如果采用「通過動畫實現(xiàn)的可視化」)。另外允許跳過「通過動畫實現(xiàn)的可視化」這一步。
2. 對于單一事件實現(xiàn)反向執(zhí)行,即撤銷這個事件造成的影響。對于「通過模板實現(xiàn)的可視化」,我們需要根據(jù)事件內(nèi)容反向撤銷它對集群數(shù)據(jù)信息的修改。對于「通過動畫實現(xiàn)的可視化」,我們什么都不用做。
時間穿梭的功能可以通過組合這兩個基礎(chǔ)操作實現(xiàn)。
1. 回退到任意歷史事件發(fā)生時刻:若想要前往的事件早于當(dāng)前呈現(xiàn)的事件,則對于這期間的事件逐一進(jìn)行反向執(zhí)行。若想要前往的事件晚于當(dāng)前呈現(xiàn)的事件,則進(jìn)行無動畫的正向執(zhí)行。
2. 從當(dāng)前事件開始單步可視化:執(zhí)行一次有動畫的正向執(zhí)行。
3. 實時展示新事件:執(zhí)行一次有動畫的正向執(zhí)行。
TiDB 事件收集TiDB 的歷史事件收集略為 Hack。由于需要過濾任何非用戶發(fā)起的查詢(類似 GC 或者 meta 查詢會由背景協(xié)程頻繁發(fā)起打擾使用體驗),因此在用戶鏈接入口處添加了 context 標(biāo)記一路攜帶到執(zhí)行層,再修改相應(yīng)的協(xié)程同步數(shù)據(jù)結(jié)構(gòu)添加需要轉(zhuǎn)發(fā)的標(biāo)記信息。比較麻煩的是類似 Point Get 這樣接口允許攜帶信息非常少的調(diào)用,只好將標(biāo)記位編碼進(jìn) Key 本身了。Plan 的可視化其實并沒有花多少功夫,因為找到 TiDB 本身已經(jīng)做了類似的功能,我們無非只是將這塊代碼直接偷來了。
PD 事件收集原本不少事件希望在 TiKV 端完成偵聽,不過顯然 KV 一小時編譯一次的效率無法滿足 Hackathon 中多次試錯的需要。因此我們改為在 PD 中偵測心跳和匯報事件。其實并沒有什么神秘,在原本 PD 自己檢查 Region 變更的代碼拆分成 Region 和 Peer 變更:每次 PD 接到 Region 心跳會在 PD Cache 中進(jìn)行 Version 和 confVer 變更的檢測,主要涉及 Peer 的增加和減少等。而 Region Split 會多帶帶由 RegionSplitReport 進(jìn)行匯報,這里也會做一次 Hook。另外就是每次心跳會檢查是否有未上報給 Lab 的 Region 信息,如果有就轉(zhuǎn)換成 Peer 信息進(jìn)行補發(fā)。
TiKV 事件收集如上,原本我們計劃了很多 TiKV 事件,但由于開發(fā)機(jī)器配置不佳,每次修改都要等待一小時進(jìn)行一次編譯,考慮到 Hackathon 上時間緊迫,因此最終大大縮減了 TiKV 上收集的事件數(shù)量,改為只收集啟動和停止。基本架構(gòu)是事件發(fā)生的時候,事件異步發(fā)送給一個 Channel,Channel 的另一端有一個異步的 worker 負(fù)責(zé)不斷處理各個事件并通過 Hyper HTTP Client 發(fā)送出去。這個流程其實與 TiKV 中匯報 PD 事件有些類似,只是事件內(nèi)容和匯報目標(biāo)不一樣。
感悟以下文字 by 馬曉宇 @ OLAP Team, PingCAP
“由于比較能調(diào)侃干的活相對少一些,所以大王要我來巡山寫感悟。”
就像隊長說的,這個項目原本是希望做一個 bRPC 替換 gRPC 的試驗,只是由于種種原因臨到 Hackathon 前夜我們才確定這是個大概率翻車的點子。于是乎我們只好在酒店里抓耳撓腮,一邊討論可能的補救措施。
參加過、圍觀過幾次 Hackathon,見過現(xiàn)場 Demo 效果最震撼的一次其實并不是一個技術(shù)上最優(yōu)秀的作品,但是它的確贏得了大獎。那是一個腦洞奇大的點子:用 Kinect 體感加上 DirectX 的全 3D 展示做的網(wǎng)絡(luò)流量實時展示;程序根據(jù)實時數(shù)據(jù)(舉辦方提供了實時網(wǎng)絡(luò)測量統(tǒng)計信息)聚合顯示不同粗細(xì)的炫酷弧光特效,而演示者則用手勢操控地球模型的旋轉(zhuǎn)。
于是在完全不了解大家是否能搞定前端的情況下,我們還是很輕率地決定了要做個重前端的項目。至于展示什么?既然時間不夠,那么秀一個需要生產(chǎn)上線的可視化工具,翻車的概率就大的多,不如直接定位為 For Educational Purpose Only。而且大概是過度解讀了炫酷對于成功的重要性,因此隊長也輕率地決定了這個項目的基調(diào)是「極盡浮夸」。就在這樣友好且不靠譜的討論氛圍下,這個項目的策劃出爐了。
之后就是艱苦卓絕連綿無休的代碼過程了。
龍毛二哥,曉峰和胡家屬的?TiNiuB Team?就在我們對面開工。講道理這其實是我個人最喜歡的項目之一。第一天放學(xué)的時候,看著他們的進(jìn)度其實我心里虛得不行:看看別人家的項目,我們的絕對主力還在折騰 TiDB Logo 動畫,是我敢怒不敢言的狀態(tài)。
原來我想偷一下懶回家睡個覺啥的,就臨時改變主意繼續(xù)配合隊長努力干活;錢同學(xué)也抱著「TiKV 一天只能 Build 24 次必須珍惜」的態(tài)度寫著人生的第一個 Rust 項目。
因此,這里必須鳴謝龍哥他們對我們的鞭策。
事實證明,誤打誤撞但又深謀遠(yuǎn)慮的浮夸戰(zhàn)略是有效的。Demo 的時候我很認(rèn)真地盯著評委:在本項目最浮夸的 Logo 展示環(huán)節(jié),大家的眼睛是發(fā)著光的,一如目睹了摩西分開紅海。我個人認(rèn)為這個動畫 Logo 生生拉高了項目 50% 的評分。
只是具體要說感悟的話(似乎好多年沒寫感悟了呢),首先這次我們?nèi)齻€組員雖然有兩個是 PingCAP 員工,不過由于技能的缺口大于人力,因此負(fù)責(zé)的任務(wù)都不是自己所屬的模塊:隊長是 TiKV 組的但是在寫前端,我是 OLAP 組的但是在改 PD 和 DB,錢同學(xué)也在做自己從來沒寫過的 Rust(參賽前一周簡單入門了一下),因此其實還蠻有挑戰(zhàn)的(笑)。然后偶爾寫寫自己不熟悉的語言,搞搞自己不熟悉的模塊,會有一種別樣的新鮮刺激感,這大概就是所謂的路邊野花更香吧(嗯)?除此之外,Hackathon 更像一個大型社交活動,滿足了貓一樣孤僻的程序員群體被隱藏的社交欲,有利于碼農(nóng)的身心發(fā)展,因此可以多搞搞 :) 。
回到我們項目本身的話,其實 TiDB 的源碼閱讀或者其他介紹類文章其實并不能非常直觀地幫助一頭霧水的初學(xué)者理解這個系統(tǒng)。我們做這個項目的最大目的是能降低學(xué)習(xí)門檻,讓所有人能以非常直觀,互動的方式近距離理解她。所以希望這個項目能給大家?guī)矸奖惆伞?/p>
TiDB Hackathon 2018 共評選出六個優(yōu)秀項目,本系列文章將由這六個項目成員主筆,分享他們的參賽經(jīng)驗和成果。我們非常希望本屆 Hackathon 誕生的優(yōu)秀項目能夠在社區(qū)中延續(xù)下去,感興趣的小伙伴們可以加入進(jìn)來哦。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/17841.html
摘要:拿到返回結(jié)果進(jìn)一步的進(jìn)行計算處理。比較痛苦的經(jīng)歷不支持,我們就只好寫內(nèi)置函數(shù),就把另外一個模塊拖下來,自己修改加上語法,然后在加上自己設(shè)計的內(nèi)置函數(shù)。其次就是涉及的的源碼模塊很多,從優(yōu)化器執(zhí)行器內(nèi)置函數(shù)以及各種各樣的結(jié)構(gòu)。 本文作者是來自 CC 組的蘭海同學(xué),他們的項目《讓 TiDB 訪問多種數(shù)據(jù)源》在本屆 TiDB Hackathon 2018 中獲得了二等獎。該項目可以讓 TiDB...
摘要:拿到返回結(jié)果進(jìn)一步的進(jìn)行計算處理。比較痛苦的經(jīng)歷不支持,我們就只好寫內(nèi)置函數(shù),就把另外一個模塊拖下來,自己修改加上語法,然后在加上自己設(shè)計的內(nèi)置函數(shù)。其次就是涉及的的源碼模塊很多,從優(yōu)化器執(zhí)行器內(nèi)置函數(shù)以及各種各樣的結(jié)構(gòu)。 本文作者是來自 CC 組的蘭海同學(xué),他們的項目《讓 TiDB 訪問多種數(shù)據(jù)源》在本屆 TiDB Hackathon 2018 中獲得了二等獎。該項目可以讓 TiDB...
閱讀 3133·2021-11-15 18:14
閱讀 1787·2021-09-22 10:51
閱讀 3303·2021-09-09 09:34
閱讀 3517·2021-09-06 15:02
閱讀 1037·2021-09-01 11:40
閱讀 3198·2019-08-30 13:58
閱讀 2536·2019-08-30 11:04
閱讀 1091·2019-08-28 18:31