作者:王運來,OceanBase 系統研發
有一個東南亞快遞公司有大量的用户諮詢與服務需求,為了降低人工成本,計劃引入#智能機器人 以代替#人工客服。
隨着近幾年#AI大模型 技術突飛猛進的發展以及在各行各業的廣泛應用,智能機器人產品也越來越成熟。只是目前市面上大部分智能機器人對中文和英文支持良好,能夠較好地理解用户輸入的信息,而對於#小語種 如泰語,支持效果並不理想。比如對於”歡迎參加北京城市交流會“,在中文語境中,智能機器人會將句子拆分為多個關鍵詞進行分析(見圖1),而在泰語語境中,若沒有合適的分詞器功能,則很難有準確的語義表述效果。

圖1 中文語境中的關鍵詞分析
比如我們要基於 #OceanBase 實現智能機器人,需要遵循圖2的向量模型框架所示的流程。當OceanBase不支持泰語分詞器時,我們需要聯繫OceanBase社區或在GitHub提需求,要求OceanBase儘快支持分詞器功能。經過評估、研發、測試等開發流程,通常需要1~3個月才能實現,時間比較久。

圖2 向量模型框架
此時,作為開發者,你該怎麼實現相關功能幫助業務解決客户需求呢?
使用插件來實現泰語的準確理解和表達就是一個不錯的選擇。目前已有企業基於OceanBase的分詞插件實現了泰語智能機器人,可以大幅提升客服效率。本文為大家講解:當需求比較急又要保證實現效果時,如何巧用插件快速響應功能需求。
如何開發自己的插件
基於OceanBase的靈活開發方式
插件 是獨立於 OBServer 的功能擴展模塊,獨立於 OceanBase 的動態庫或者Jar包,或者其它語言的運行包,可單獨發佈、加載與升級,無需替換 OceanBase 核心二進制文件,其核心特徵有三點。
1. 低耦合,開發週期短。
在傳統模式下,任何新功能都必須合併進 OceanBase 內核源碼,從需求評審到代碼合入通常需要 1–3 個月。而插件與 OBServer隔離,生命週期獨立,可以獨立發佈、單獨加載、獨立升級,Bug 修復或功能增強僅需更新插件,不影響數據庫內核。
2. 更開放,更低的開發門檻。
開發者遵循公開 API 即可實現任意功能,不受OceanBase內核編碼規範的約束。而且開發者可以使用自己熟悉的#編程語言,比如 C/C++、Java、Python 等,自行決定運行環境。此外,開發者可自由選擇 C++ 標準庫、異常處理模型或其他第三方依賴,只需在插件邊界做好異常捕獲與資源管理,即可保證與 OceanBase 的穩定對接。
3. 自定義,代碼自主可控。
個人開發者或企業開發者可按需定製私有功能,代碼自己掌控,不受 OceanBase 木蘭許可證的約束,可以商用,也可以貢獻給OceanBase公共插件倉庫。
總的來説,插件機制在功能、使用及維護層面均保持與 OceanBase 內核的最低耦合度,並具備靈活、安全且可持續演進的擴展方案。而其開放的特性,為個人開發者和企業提供了多樣化選擇。
插件的開發方式和使用方法
開發插件
為方便開發者上手,我們推出了開發套件,每種類型插件都有其開發樣例代碼。當大家安裝開發套件後,可以直接複製樣例代碼到自己的開發目錄中,在此基礎上調整代碼更加簡便。插件動態庫和內核代碼在一起運行,沒有沙箱機制,因此一定要經過充分的測試。如果插件運行不穩定,比如內存訪問錯誤問題,運行時會導致整個 OceanBase 進程宕機,因此,建議大家根據自定義功能在生產發佈前進行充分的測試。
歡迎大家把代碼發佈在 OceanBase 的 GitHub 倉庫中(https://github.com/oceanbase/oceanbase),開放共享。目前已開放的插件 License 遵循 Apache 2.0 協議,可以進行商業的二次開發,也歡迎大家試用。
插件機制以高度開放的方式,支持在 OceanBase 內核之外獨立擴展功能,提供Plugins和OceanBase Kernel接口(見圖3 )。

圖3 插件接口
Plugins
- Plugin Interfaces:已知存在多種插件,包括外表插件、分詞器插件,每種插件將對應一套已定義好的接口(Plugin Interfaces),插件實現這些接口即可完成與數據庫的集成。
- Plugin API:同時插件也可能需要調用內核能力,例如使用內核的內存分配器等,為此 OceanBase 提供了內核接口即 Plugin API。
插件接口 Plugin Interfaces 和內核接口 Plugin API 都是插件和數據庫內核之間的屏障,可以實現獨立升級,並且在升級時儘量保持兼容。
OceanBase Kernel
- Plugin Interface Adaptor:插件適配器,用於適配不同類型的插件。以分詞器為例,分詞器接口 Plugin Interfaces 是以 C 語言實現的,OceanBase Kernel 內部其他的分詞器如 IK 分詞器或 N-gram 分詞器是使用 OceanBase 的代碼語言 C++ 實現的,如果需要把外部插件轉換到內部進行調用,插件適配器可以屏蔽掉插件接口在升級以及兼容上的細節問題,使得內核和插件升級等的工作量儘量小。
- Plugin Manager:用於插件管理,管理某一類插件中具體包含哪些插件,例如分詞器插件包括哪些插件,外表插件有哪些插件等。
使用插件
插件的用法比較簡單,C/C++編寫的插件編譯後是一個動態庫,Java是一個Jar包。將動態庫或Jar 包放在指定目錄或用户配置的目錄,修改配置項後再重啓(如果使用 OBD 部署,可以直接使用 OBD 重啓集羣命令 obd cluster restart + 集羣名重啓)即可使用插件。
現有插件:分詞器和外表
OceanBase 目前有分詞器插件和外表插件兩種插件,都提供了對應的接口和樣例代碼,同時 OceanBase 也實現了對中文支持比較友好的結巴分詞器插件。
分詞器插件
OceanBase的分詞器插件具有三個主要特性:多語言、行業定製、系統兼容(見圖4)。

圖4 OceanBase分詞器插件的主要特性
多語言。OceanBase 分詞器的功能接口都比較簡單易用,可用場景豐富。例如前文提到的泰語分詞器,對於在東南亞有業務的用户,使用泰語分詞器可以更好地服務東南亞業務,同時用户也可以根據業務需求個性化擴展多語言分詞器如韓語分詞器。
行業定製。除了支持多語言分詞器,基於不同行業的應用場景,例如醫療、法律、金融等包含特定詞語的特定行業,也可以定製自己的分詞器以及詞庫從而更精確地識別特定場景。
兼容多個系統。如果需要在一個系統中同時運行多種系統,如 Elasticsearch、Amazon OpenSearch Service等,可以通過插件讓它們表現得儘可能接近,例如在 Elasticsearch中使用其他分詞器,可以按照 Elasticsearch分詞器寫一個插件在 OceanBase 中使用,在集成大系統時各產品組件之間會更加融洽。
結巴分詞插件
圖5是#結巴分詞器 的使用示例,可以看到結巴分詞器對中文的支持很友好,可以良好實現對中文和中英文結合的需求。結巴分詞器代碼請參考:https://github.com/oceanbase/oceanbase-plugins/tree/main/jieba_ftparser。

圖5 結巴分詞器的使用示例
外表插件
在介紹外表插件前,先簡單介紹下外表的概念,以便大家更好地理解。以 OceanBase 外表為例,可以通過 OceanBase 客户端直接連接 OceanBase 並創建一個外表,訪問 #MySQL 或 ODPS甚至是一些本地目錄中的 CSV 文件。同時,外表也可以和 OceanBase 中的表進行關聯查詢,更便於數據分析。外表插件代碼請參考:https://github.com/oceanbase/oceanbase-plugins/tree/main/external_table。
外表意味着用户無需將 CSV 或 MySQL 數據導入 OceanBase,就可以直接和 OceanBase 內部的表進行關聯查詢,實現了多源合一(見圖6 )。當前支持主流的數據源如 HDFS、Kafka、MySQL 等,以及CSV、ORC、Excel 等數據文件,大家可以根據需求靈活定製。對於數據文件類型,OceanBase 已經實現了 CSV、Parquet、ORC等,如果有 Excel、Doc 等其他需求,可以通過接口定製,將插件裝到 OceanBase 後即可使用。

圖6 外表的價值
此外,企業內部可能有一些和標準格式不同的數據格式,如果不使用插件方式,需要先轉化數據格式,效率較低。在這種情況下,企業便可以直接開發插件並應用於內部,提高效率。
圖7是 OceanBase 的外表產品圖,支持通過 OceanBase 引擎直接訪問不同格式、不同存儲方式(如雲上 S3 、OSS)的外部數據。當然這些數據格式不僅包含使用外表插件實現的功能,也包含了一些內嵌在 OceanBase 中的功能、數據湖功能等,都可以直接通過 OceanBase 進行查詢。

圖7 OceanBase 外表產品圖
如果大家有興趣深入理解插件的實現過程,可以先了解外表 TableScan 的實現。如圖8所示,TableScan 是表掃描的接口,針對不同類型的表需要實現不同的 AccessServce,其中: ObAccessServce 對應 OceanBase 內部表;ObVirtualDataAccessService 對應 OceanBase 內部的虛擬表;ObExternalTableAccessService 對應外部表。外部表的查詢類 ExternalTableScan 可以根據不同數據類型創建出不同的行迭代器,如 MySQL 是基於 JdbcRowIterator 實現的,加載了 JDBC 驅動,同時對於 PG 以及支持 JDBC 驅動的數據庫也可以輕鬆擴展。

圖8 TableScan 的實現
來吧,實現你的插件
基於上述插件體系的解讀,相信已有功能需求的開發者已經瞭解到自己接下來該如何做。對於暫無功能需求的開發者,當前 OceanBase 已提供兩類插件框架,但可選類型仍較為有限。我們歡迎並接納大家的創意和需求,以豐富插件類型:無論是審計接口、認證接口,還是其他任何類型的插件設想,均可提出。
在插件開發過程中,如需調用內核功能、訪問 OceanBase 的系統變量或實現可配置化支持,我們可以協同解決。除了目前 OceanBase 已支持的 C++ 及外表的 Java 語言外,如果對 Python、Rust 或其他語言有需求,也可以和社區聯繫,我們將共同評估並拓展多語言支持。
對 OceanBase 插件開發感興趣的小夥伴歡迎掃碼加入 OceanBase 插件開發者交流羣,羣內會不定時同步插件產品相關資訊。

最後為大家推薦這個 OceanBase 開源負責人老紀的公眾號「老紀的技術嘮嗑局」,會持續更新和 #數據庫、#AI、#技術架構 相關的各種技術內容。歡迎感興趣的朋友們關注!
「老紀的技術嘮嗑局」不僅希望能持續給大家帶來有價值的技術分享,也希望能和大家一起為開源社區貢獻一份力量。如果你對 OceanBase 開源社區認可,點亮一顆小星星✨吧!你的每一個Star,都是我們努力的動力。