日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql递归查询所有上下节点_【转】MySQL之Spider存储引擎原理详解

發(fā)布時(shí)間:2025/4/16 数据库 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql递归查询所有上下节点_【转】MySQL之Spider存储引擎原理详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、概述

Spider是為MySQL/MariaDB開發(fā)的一個(gè)特殊引擎,具有內(nèi)嵌分片功能。MariaDB從10.0.4開始支持Spider。作為MariaDB的一個(gè)新的主要特性。Spider的主要功能是將數(shù)據(jù)分散到多個(gè)后端節(jié)點(diǎn),它的作用類似于一個(gè)代理。
Spider有三個(gè)作用:

  • 作為分庫分表的中間件;
  • 支持像訪問本地?cái)?shù)據(jù)表一樣訪問遠(yuǎn)端表(進(jìn)行普通查詢、跨表Join和DML等);
  • 業(yè)務(wù)和數(shù)據(jù)庫間的代理(Proxy)。
  • MySQL和Spider的架構(gòu)圖:


    Spider是由日本的MySQL開發(fā)者Kentoku Shiba創(chuàng)建和開發(fā)的存儲(chǔ)引擎,騰訊數(shù)據(jù)庫團(tuán)隊(duì)貢獻(xiàn)了非常多Patch。據(jù)說騰訊游戲、騰訊支付等有大規(guī)模使用。

    二、表鏈接

    Spider的表鏈接的技術(shù)參考ISO/IEC 9075-9:2008 SQL/MED標(biāo)準(zhǔn)。利用Spider的這個(gè)特性,你可以像操作本地MariaDB實(shí)例的表一樣來操作分布在多個(gè)MariaDB實(shí)例上的表。
    Spider表是個(gè)虛擬表,本身不存儲(chǔ)數(shù)據(jù)。當(dāng)創(chuàng)建一個(gè)Spider存儲(chǔ)引擎的表時(shí),該表指向單個(gè)或多個(gè)后端MariaDB實(shí)例上對(duì)應(yīng)的表。后端實(shí)例上的表可以是任何存儲(chǔ)引擎的表。Spider的系統(tǒng)表spider_tables記錄了各個(gè)數(shù)據(jù)分片的實(shí)例位置、連接、狀態(tài)等信息(如下圖中TABLE和PART部分)。該系統(tǒng)表可以便利Spider跨節(jié)點(diǎn)的join操作:訪問數(shù)據(jù)所在的機(jī)器,然后把數(shù)據(jù)拉取到本地進(jìn)行join操作;如果進(jìn)行join操作字段不是分片字段,那么需要廣播SQL語句將數(shù)據(jù)拉取到Spider節(jié)點(diǎn)進(jìn)行join操作。

    在執(zhí)行CREATE TABLE命令創(chuàng)建Spider引擎的表時(shí),通過添加COMMENT或CONNECTION語法來指定后端實(shí)例的地址等信息。多個(gè)實(shí)例時(shí),通過PARTITION語法來指定。
    在Spider節(jié)點(diǎn),表字段定義可以忽略。Spider第一次訪問表的時(shí)候,如果發(fā)現(xiàn)沒有表字段定義,會(huì)從后端節(jié)點(diǎn)拉取相關(guān)元數(shù)據(jù),然后緩存在本地。

    2.1 水平分表

    水平分表應(yīng)該是最常用的模式,類似于現(xiàn)有MySQL中間件的分庫分表,或者手動(dòng)分庫分表。可以將一張表拆分為多個(gè)分區(qū),每個(gè)分區(qū)保存一部分?jǐn)?shù)據(jù)。如下所示:

    Spider支持MySQL/MariaDB所有類型的分區(qū)表,有Range、Hash、List、Key分區(qū)。下面演示的基于Range分區(qū)。
    例如,在2個(gè)節(jié)點(diǎn)上創(chuàng)建如下表:

    CREATE

    然后在spider節(jié)點(diǎn)上創(chuàng)建如下表來鏈接2個(gè)節(jié)點(diǎn)的表:

    CREATE

    2.2 垂直分表

    垂直分表可以使用在多個(gè)不同的場(chǎng)景,包括將多個(gè)數(shù)據(jù)庫實(shí)例的表映射到同個(gè)數(shù)據(jù)庫實(shí)例上。這既可以實(shí)現(xiàn)跨表Join,又可以起到數(shù)據(jù)垂直拆分的效果。如下圖所示:

    業(yè)務(wù)將用戶的不同類型信息user_info、user_msg、user_detail和user_log分別保存到不同實(shí)例上實(shí)現(xiàn)垂直擴(kuò)展,業(yè)務(wù)可以直接訪問這些表進(jìn)行DML操作,相互間沒有干擾,這樣可以解除單臺(tái)服務(wù)器的存儲(chǔ)和計(jì)算資源瓶頸。但畢竟它們都屬于用戶信息,有多表查詢的需求,所以可以將這些表映射到獨(dú)立的Spider實(shí)例上,業(yè)務(wù)通過Spider實(shí)例進(jìn)行普通查詢操作,包括跨表的各種Join,還可以在Spider實(shí)例上進(jìn)行各種統(tǒng)計(jì)和分析操作。當(dāng)然,業(yè)務(wù)也可以通過Spider實(shí)例統(tǒng)一對(duì)這些表進(jìn)行DML操作,通過部署多個(gè)Spider實(shí)例實(shí)現(xiàn)訪問的負(fù)載均衡。
    例如,先在兩個(gè)后端節(jié)點(diǎn)分別創(chuàng)建如下的一個(gè)表:

    CREATE

    然后在spider節(jié)點(diǎn)上鏈表兩個(gè)后端節(jié)點(diǎn):

    CREATE

    三、事務(wù)

    Spider分別針對(duì)單機(jī)事務(wù)與XA事務(wù)實(shí)現(xiàn)了相應(yīng)的操作事務(wù)的方法。下圖列出了兩者部分實(shí)現(xiàn)的方法。

    上述方法的主要實(shí)現(xiàn)是向后端節(jié)點(diǎn)發(fā)送消息,有些階段同時(shí)需要執(zhí)行記錄系統(tǒng)表的行為。Spider依賴后端數(shù)據(jù)節(jié)點(diǎn)保證事務(wù)的持久性以及隔離性。它只負(fù)責(zé)開啟事務(wù),以及在適當(dāng)?shù)臅r(shí)機(jī)發(fā)送提交或者回滾事務(wù)的命令。如果單機(jī)事務(wù)涉及多個(gè)數(shù)據(jù)節(jié)點(diǎn),Spider需要將相應(yīng)的連接保存在隊(duì)列中。在事務(wù)提交或者回滾的時(shí)候,逐個(gè)發(fā)送相應(yīng)的命令。

    3.1 分布式事務(wù)DTP/XA模型

    Spider分布式XA事務(wù)的實(shí)現(xiàn)參照了分布式事務(wù)DTP/XA模型(如下圖)。在這個(gè)模型中,有三個(gè)角色:

  • RM(Resource Manager,資源管理器)
  • TM(Transaction Manager, 事務(wù)管理器)
  • AP(Application, 應(yīng)用程序)
  • AP通過RM API來操作和管理資源,通過TM接口開啟/終止/結(jié)束事務(wù)。RM與TM之間需要實(shí)現(xiàn)XA接口。XA接口定義了兩階段提交的必要步驟,以及RM與TM之間需要進(jìn)行的交互。
    其兩階段提交步驟如下:

    XA

    DTP/XA模型圖示:

    3.2 Spider事務(wù)的實(shí)現(xiàn)

    Spider扮演的是TM角色,而后端的數(shù)據(jù)節(jié)點(diǎn)扮演的是RM的角色。
    在Spider中,XA事務(wù)分別有四種狀態(tài),如下圖,對(duì)應(yīng)于NOT YET,PREPAED,ROLLBACK以及COMMITTED。Spider在開始PREPARE階段之際會(huì)在系統(tǒng)表spider_xa中標(biāo)記該XA事務(wù)的狀態(tài)為NOT YET。在所有數(shù)據(jù)節(jié)點(diǎn)都接收到PREPARE消息以后,該XA事務(wù)的狀態(tài)進(jìn)入到PREPARED階段。假如在PREPARE階段,某一個(gè)數(shù)據(jù)節(jié)點(diǎn)發(fā)生故障,那么Spider會(huì)回滾該事務(wù)。相應(yīng)地,事務(wù)的狀態(tài)變成ROLLBACK。
    最后,如果所有參與事務(wù)的節(jié)點(diǎn)都返回PREPARE OK,該事務(wù)進(jìn)入提交階段。

    執(zhí)行XA事務(wù),Spider與兩個(gè)后端節(jié)點(diǎn)的詳細(xì)交互步驟:


    從上圖可以看到Spider向后端節(jié)點(diǎn)發(fā)送XA START命令時(shí)會(huì)設(shè)置會(huì)話級(jí)別的事務(wù)特性,同時(shí)將XA事務(wù)ID發(fā)送到后端節(jié)點(diǎn)。因?yàn)閄A事務(wù)ID由三部分組成,Spider會(huì)將這三個(gè)部分的解析出來,然后拼接成對(duì)應(yīng)的字符串發(fā)送到后端節(jié)點(diǎn)。為了節(jié)省網(wǎng)絡(luò)開銷,Spider將XA END與XA PREPARE命令合并起來一起發(fā)送。也就是在這個(gè)階段初始,Spider在系統(tǒng)表里面記錄事務(wù)的狀態(tài)。如果所有的RM都返回OK,那么Spider進(jìn)入PREPARED狀態(tài),準(zhǔn)備提交事務(wù)。否則,事務(wù)進(jìn)入到回滾狀態(tài)。

    四、讀寫流程

    為了更清楚地了解Spider的讀寫流程,我們有必要研究一下數(shù)據(jù)庫系統(tǒng)的查詢執(zhí)行模型,以及MySQL的插拔式引擎如何跟這個(gè)模型對(duì)接的。
    數(shù)據(jù)庫系統(tǒng)基本都采用迭代器模型處理查詢,也叫volcano查詢執(zhí)行引擎(發(fā)明這個(gè)詞的學(xué)者大概是因?yàn)椴樵儓?zhí)行計(jì)劃樹看起來像一座火山,如下圖)。執(zhí)行計(jì)劃樹的上層節(jié)點(diǎn)通過get_next方法驅(qū)動(dòng)子節(jié)點(diǎn)獲取一條元組,子節(jié)點(diǎn)遞歸調(diào)用。在葉子節(jié)點(diǎn)也就是基本表將數(shù)據(jù)返回。
    這個(gè)模型的一個(gè)好處就是實(shí)現(xiàn)起來很優(yōu)雅,同時(shí)數(shù)據(jù)流與控制流結(jié)合在一起方便程序的調(diào)試。這個(gè)模型的缺點(diǎn)是函數(shù)的大量調(diào)用使得進(jìn)程/線程上下文切換頻繁,程序的局部性受到損害。因此,后來針對(duì)OLAP場(chǎng)景,采用了向量查詢執(zhí)行模型來減少進(jìn)程上下文的切換以及保證保證高速緩存的命中率。
    再次以下圖為例子,圖中的SQL語句的功能是查詢一個(gè)部門的平均薪資。假如在職工表EMP的員工ID字段Dno上存在索引,MySQL在Server層針對(duì)該查詢語句生成的查詢計(jì)劃如下:順序掃描部門表,通過索引訪問職工表,然后在兩表join操作之后進(jìn)行投影操作。下一個(gè)階段為分組排序操作。上層的操作算子(例如join),驅(qū)動(dòng)子節(jié)點(diǎn)調(diào)用get_next方法(表掃描方法)獲取一條元組。底層操作算子(表訪問方法,handler接口定義)將數(shù)據(jù)返回。至此,我們可以總結(jié)一下MySQL體系的工作原理:查詢執(zhí)行計(jì)劃由MySQL Server層生成,存儲(chǔ)引擎受執(zhí)行計(jì)劃驅(qū)動(dòng)而訪問表。MySQL的handler已經(jīng)定義好表的訪問方法,實(shí)現(xiàn)了這些訪問方法的存儲(chǔ)引擎就可以作為MySQL的插件式引擎而存在。
    查詢計(jì)劃樹示例:

    下面我們對(duì)Spider的讀寫流程結(jié)合Server層代碼進(jìn)行分析。

    4.1 SELECT操作

    上面提到Spider的作用類似一個(gè)proxy,本身并不存儲(chǔ)數(shù)據(jù)。因此Spider處理SELECT語句(UPDATE與DELETE類似)首先需要根據(jù)查詢解析的信息生成一個(gè)SELECT語句,發(fā)送到查詢涉及的后端節(jié)點(diǎn),將數(shù)據(jù)從遠(yuǎn)端拉到本地,然后進(jìn)行處理。函數(shù)spider_db_append_select_columns根據(jù)查詢涉及的讀集以及寫集獲取相應(yīng)的字段,構(gòu)造一個(gè)SQL語句從后端節(jié)點(diǎn)拉取數(shù)據(jù)到本地。如果涉及多個(gè)分片,spider將從不同實(shí)例獲取過來的結(jié)果集存放在不同的結(jié)果集spider_db_result中。類spider_db_fetch提供了fetch_next, current_row等方法供上層方法調(diào)用。Server層調(diào)用get_next方法驅(qū)動(dòng)引擎層獲取下一條數(shù)據(jù)。
    對(duì)于表訪問方法,MySQL實(shí)現(xiàn)了索引掃描(ha_index_read)與隨機(jī)訪問(ha_rnd_next)的方法。對(duì)于切分為多個(gè)分片的DB,索引掃描需要借助優(yōu)先隊(duì)列。索引掃描需要區(qū)分是否是第一次調(diào)用該方法。如果是第一次調(diào)用該方法,需要遍歷所有的分片讀取一條記錄,然后插入到優(yōu)先隊(duì)列。對(duì)應(yīng)到Spider,如果第一次調(diào)用訪問遠(yuǎn)端實(shí)例表的方法,需要生成SELECT語句,將遠(yuǎn)端實(shí)例的數(shù)據(jù)拉到本地存放。在使用索引掃描的情況,MySQL 為每個(gè)分片保留一個(gè)key buffer以及record buffer。server 利用隊(duì)列頭部的m_top_entry 獲得訪問的分片ID。接著,調(diào)用get_next方法獲取相應(yīng)的元組,將返回的數(shù)據(jù)存放在record buffer,并插入到優(yōu)先隊(duì)列。函數(shù)最后將元組從優(yōu)先隊(duì)列返回。
    為緩解內(nèi)存等資源的壓力,Spider實(shí)現(xiàn)全表掃描的方法是逐個(gè)分片串行掃描(為了加速,spider也提供了并行掃描數(shù)據(jù)節(jié)點(diǎn)的選項(xiàng))。如下兩圖給出了Spider對(duì)于上述兩種表訪問方法的實(shí)現(xiàn)機(jī)制。
    索引掃描實(shí)現(xiàn):

    全表掃描:

    4.2 INSERT操作

    MySQL的handler類對(duì)于INSERT操作提供的接口函數(shù)的名字是write_row。存儲(chǔ)引擎想要支持INSERT操作就必須實(shí)現(xiàn)write_row方法。Spider對(duì)于write_row方法的實(shí)現(xiàn)是簡單地根據(jù)查詢解析的信息拼接一條INSERT語句,發(fā)往后端節(jié)點(diǎn)處理。如果是批量插入操作則需要與MySQL Server層配合,將INSERT語句批量發(fā)到后端節(jié)點(diǎn)。
    下圖結(jié)合一條批量插入的INSERT語句給出MySQL中INSERT操作的具體實(shí)現(xiàn)。

    mysql_insert調(diào)用write_row執(zhí)行具體的插入操作(第8行)。這是存儲(chǔ)引擎必須實(shí)現(xiàn)的方法。對(duì)應(yīng)于spider,spider根據(jù)查詢涉及到的列(field)拼成一條INSERT語句(如果是分片數(shù)據(jù)庫,VALUSE中的列必須包含分區(qū)鍵,分區(qū)鍵是自增列的情況除外)。圖9中的QUERY將用戶ID(ID)和用戶名(Name)插入到user表,其中ID是分區(qū)鍵。mysql_insert根據(jù)VALUES包含的元組數(shù)目,判斷是否需要進(jìn)行批量插入操作。該例子的QUERY的VALUES包含4條元組,所有需要進(jìn)行批量插入操作。MySQL循環(huán)調(diào)用write_row方法觸發(fā)spider生成INSERT語句。Spider的write_row方法實(shí)現(xiàn)中會(huì)根據(jù)分區(qū)鍵將INSERT語句進(jìn)行分組(第5行~第9行)。圖9給出的實(shí)例只有兩個(gè)數(shù)據(jù)分片,所以SQL語句被分成兩組。處理完VALUES以后,Spider的INSERT語句也拼接完成。
    ha_end_bulk_insert方法通知Spider完成VALUES處理。此時(shí),Spider將INSERT發(fā)送到后端節(jié)點(diǎn)進(jìn)行處理(第11行)。

    4.3 DELETE實(shí)現(xiàn)

    Spider想要支持DELETE操作必須實(shí)現(xiàn)MySQL handler類提供的ha_delete_row方法。與INSERT操作不同,DELETE操作需要生成一條SELECT語句將查詢涉及的分區(qū)鍵拉到Spider節(jié)點(diǎn)。這是因?yàn)镸ySQL Server層的“once-a-tuple”的查詢執(zhí)行模型(實(shí)際上基本所有的關(guān)系數(shù)據(jù)庫系統(tǒng)都采用該模型)會(huì)驅(qū)動(dòng)Spider逐個(gè)拼接DELETE語句,然后發(fā)往后端節(jié)點(diǎn)。這時(shí)候,Spider需要知道對(duì)應(yīng)的DELETE語句該往哪個(gè)后端節(jié)點(diǎn)發(fā)送。為了減少網(wǎng)絡(luò)開銷,Spider提供了批量發(fā)送DELETE語句的功能。
    Spiderpider中delete的實(shí)現(xiàn)如下:

    MySQL Server層首先確定表的訪問方法:采用索引掃描或者全部掃描(第5行)?DELETE方法需要執(zhí)行一次查找操作,調(diào)用get_next方法(info.read_record)獲取一條元組(第10行)。Spider需要判斷是否第一次調(diào)用get_next方法。如果是的話,則需要生成SELECT語句,將數(shù)據(jù)節(jié)點(diǎn)的數(shù)據(jù)拉到本地。否則,Spider直接從本地返回?cái)?shù)據(jù)給上層調(diào)用者。接下來,Server層調(diào)用ha_delete_row方法將數(shù)據(jù)刪除。這是存儲(chǔ)引擎需要具體實(shí)現(xiàn)的方法。由于Spider本身并不存儲(chǔ)數(shù)據(jù)的緣故,其實(shí)現(xiàn)delete操作主要思想是利用從后端節(jié)點(diǎn)拉取過來的數(shù)據(jù)(分區(qū)鍵,過濾條件等),拼接成一條DELETE語句。然后,發(fā)送該請(qǐng)求到數(shù)據(jù)節(jié)點(diǎn)。Spider為了優(yōu)化網(wǎng)絡(luò)開銷,提供了批量發(fā)送DELETE語句的選項(xiàng)。
    UPDATE操作的實(shí)現(xiàn)類似DELETE,都需要Spider生成SELECT語句從后端節(jié)點(diǎn)拉取數(shù)據(jù)。只不過,UPDATE在更新區(qū)分鍵的時(shí)候,可能需要多一次DELETE操作(刪除原來分區(qū)的數(shù)據(jù),將新的數(shù)據(jù)插入到不同的分區(qū))。

    4.4 其他說明

    在Spider表上進(jìn)行的DML和查詢操作均下發(fā)到后端數(shù)據(jù)節(jié)點(diǎn)。在HA(高可用,后面會(huì)介紹)模式下,Spider能夠進(jìn)行負(fù)責(zé)均衡,將查詢請(qǐng)求分?jǐn)偟讲煌臄?shù)據(jù)幾點(diǎn)上。對(duì)于DML操作,不管是HA模式還是分表模式,Spider節(jié)點(diǎn)均對(duì)數(shù)據(jù)節(jié)點(diǎn)進(jìn)行并發(fā)地?cái)?shù)據(jù)增刪改。涉及到多個(gè)數(shù)據(jù)節(jié)點(diǎn)的DML操作,Spider基于兩階段事務(wù)實(shí)現(xiàn)數(shù)據(jù)的一致性。


    對(duì)于DDL操作情況有些不一樣。對(duì)于Spider表進(jìn)行drop table操作不會(huì)影響后端數(shù)據(jù)節(jié)點(diǎn),也就是說數(shù)據(jù)節(jié)點(diǎn)對(duì)應(yīng)的表不會(huì)被刪除。類似地,對(duì)Spider節(jié)點(diǎn)進(jìn)行alter table加索引或刪索引等操作也不會(huì)影響后端數(shù)據(jù)。但若執(zhí)行truncate table,則后端數(shù)據(jù)節(jié)點(diǎn)的表也會(huì)被清空。

    五、性能優(yōu)化

    為了提高性能,還支持多種功能,包括使用DirectSQL直接操作后端數(shù)據(jù)節(jié)點(diǎn),各種下推(push down)優(yōu)化等。

    5.1 DirectSQL

    Spider作為MySQL的一個(gè)可插拔引擎,實(shí)現(xiàn)了handler類定義的相應(yīng)的存取方法。Spider本身并不存放數(shù)據(jù),而是類似一個(gè)代理的功能將訪問請(qǐng)求路由到后端的數(shù)據(jù)節(jié)點(diǎn)。Spider提供了兩種途徑訪問后端節(jié)點(diǎn)存儲(chǔ)的數(shù)據(jù)。
    MySQL體系下的Spider:

    如上圖所示,Spider可以遵循MySQL傳統(tǒng)的查詢處理流程來訪問數(shù)據(jù),也開發(fā)了自有的一套來加速數(shù)據(jù)訪問。在傳統(tǒng)的查詢處理方式下,SQL查詢請(qǐng)求經(jīng)過查詢解析、查詢重寫、查詢優(yōu)化等步驟。按照生成的查詢執(zhí)行計(jì)劃,Spider從后端節(jié)點(diǎn)拉取數(shù)據(jù),交給MySQL服務(wù)器處理。Spider在這種查詢處理框架之下的一個(gè)缺點(diǎn)是不能很好地利用后端節(jié)點(diǎn)可并行化特性,同時(shí)需要對(duì)SQL查詢進(jìn)行兩次解析,帶來的性能損耗問題比較嚴(yán)重。
    有測(cè)試表明,傳統(tǒng)處理方式性能損耗約50%左右。基于這個(gè)原因,為了加速聚集、統(tǒng)計(jì)等查詢,Spider開發(fā)團(tuán)隊(duì)提供了DirectSQL方式執(zhí)行查詢。DirectSQL的原理類似于Map Reduce方案,將查詢直接下發(fā)到后端節(jié)點(diǎn),無需在MySQL服務(wù)器層進(jìn)行解析(Map階段);后端節(jié)點(diǎn)將結(jié)果返回給Spider,由Spider合并結(jié)果集(Reduce階段)。這個(gè)方式很好地利用后端節(jié)點(diǎn)可并行處理查詢的特點(diǎn),消除重復(fù)解析SQL語句的行為。
    Spider提供了2個(gè)DirectSQL,分別是SPIDER_DIRECT_SQL和SPIDER_BG_DIRECT_SQL。其用法如下:

    SPIDER_DIRECT_SQL

    DirectSQL它會(huì)直接在parameters參數(shù)指定的遠(yuǎn)端節(jié)點(diǎn)執(zhí)行sql參數(shù)指定的SQL,并將結(jié)果保存在tmp_table_list指定的臨時(shí)表上,parameters一般指定為在mysql.servers中定義的一到多個(gè)后端數(shù)據(jù)節(jié)點(diǎn)server。類似于MapReduce機(jī)制,直接將SQL并行發(fā)送給指定的server(Map過程),將結(jié)果集返回給Spider節(jié)點(diǎn),由其經(jīng)過處理后返回給客戶端(Reduce階段)。操作如下所示:

    SELECT

    5.2 下推(Push Down)

    5.2.1 聚合下推

    將min、max、avg、count和sum等常用的聚合操作直接下推到數(shù)據(jù)節(jié)點(diǎn),再聚合數(shù)據(jù)節(jié)點(diǎn)返回的結(jié)果。

    5.2.2 Update/Delete下推

    如果是批量更新或刪除,Spider將整個(gè)Update/Delete操作下推到數(shù)據(jù)節(jié)點(diǎn),而不是在Spider節(jié)點(diǎn)解析Values后逐條下發(fā)到數(shù)據(jù)節(jié)點(diǎn)。

    5.2.3 Join下推

    與聚合操作、DML操作類似,Join操作也可以直接下推到數(shù)據(jù)節(jié)點(diǎn),Spider僅做結(jié)果集處理。除此之外,Spider還支持引擎條件(Engine Condition)下推、索引hints下推等,這些下推操作即減少了Spider節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)重復(fù)的SQL解析優(yōu)化,又減少了返回給Spider的結(jié)果集大小,可以節(jié)省系統(tǒng)的資源消耗,并提高實(shí)例的性能。

    六、高可用

    Spider支持分區(qū)加HA(High Availability)的部署方式,實(shí)現(xiàn)數(shù)據(jù)水平擴(kuò)展的同時(shí)實(shí)現(xiàn)數(shù)據(jù)高可靠和高可用。部署模式參考如下:

    在上圖中,部署3個(gè)Spider節(jié)點(diǎn)用于服務(wù)高可用和負(fù)載均衡,分布表TABLE1有3個(gè)分區(qū),Spider下面有3個(gè)數(shù)據(jù)節(jié)點(diǎn),每個(gè)數(shù)據(jù)節(jié)點(diǎn)保存2個(gè)分區(qū)的數(shù)據(jù)。每個(gè)分區(qū)的數(shù)據(jù)均放置在2個(gè)數(shù)據(jù)節(jié)點(diǎn)上。多個(gè)數(shù)據(jù)節(jié)點(diǎn)的同一個(gè)分區(qū)也是通過兩階段提交來保證數(shù)據(jù)一致。
    下面部署方式示例:

    CREATE

    七、其他

    7.1 性能

    下圖是MariaDB官方文檔中提供的性能指標(biāo)。


    上圖為sysbench只讀場(chǎng)景下,MariaDB(InnoDB)、Spider和其他Proxy套件的性能對(duì)比,可以發(fā)現(xiàn)在低并發(fā)場(chǎng)景下Spider處于弱勢(shì),但并發(fā)數(shù)達(dá)到128以上,除了Spider和HaProxy,MariaDB和MySQL-Proxy性能均有急劇下降。

    上圖為讀寫操作在不同Spider表數(shù)據(jù)冗余下的性能對(duì)比,可以發(fā)現(xiàn)副本多了對(duì)讀幫助較大,對(duì)寫影響較小。

    7.2 優(yōu)缺點(diǎn)

    Spider最大的優(yōu)勢(shì)是在數(shù)據(jù)庫進(jìn)程內(nèi)部實(shí)現(xiàn)了分庫分表和跨節(jié)點(diǎn)的表復(fù)雜查詢,這樣容易做到跟MySQL協(xié)議的100%兼容。依托于成熟而靈活的MySQL插件式存儲(chǔ)引擎框架,可以進(jìn)一步堆疊/擴(kuò)展更多高級(jí)功能,比如后端節(jié)點(diǎn)的探活和自動(dòng)切換,多個(gè)Spider節(jié)點(diǎn)的負(fù)載均衡等。可以說,基于引擎插件層進(jìn)行MySQL功能特性擴(kuò)展是個(gè)非常不錯(cuò)的方向。
    Spider的缺點(diǎn)在于用戶數(shù)還是太少,功能集未經(jīng)過大規(guī)模驗(yàn)證,成熟度不高。此外文檔偏少,功能也還不夠豐富。Spider的優(yōu)勢(shì):

    a、對(duì)業(yè)務(wù)透明,業(yè)務(wù)程序可以不用修改或做非常少的修改。業(yè)務(wù)連接到Spider節(jié)點(diǎn),具體訪問哪個(gè)數(shù)據(jù)節(jié)點(diǎn)由Spider處理,無需放在業(yè)務(wù)邏輯中;
    b、方便水平擴(kuò)展,能解決單個(gè)服務(wù)器的計(jì)算和存儲(chǔ)資源瓶頸問題。擴(kuò)展能力可以是無窮的;
    c、支持多種后端數(shù)據(jù)節(jié)點(diǎn)類型,比如后端節(jié)點(diǎn)可以是MariaDB,也可以是MySQL,甚至是Oracle(MariaDB目前暫不支持);
    d、拆分方式靈活。可以根據(jù)需求實(shí)現(xiàn)垂直拆分和水平拆分功能,水平拆分支持基于分區(qū)表,可支持哈希、范圍、列表等算法;
    e、完全兼容MySQL協(xié)議,由于Spider位于存儲(chǔ)引擎層,基于分區(qū)表實(shí)現(xiàn)數(shù)據(jù)拆分,所以MySQL的所有SQL在Spider均可以進(jìn)行適配。這是Spider相比傳統(tǒng)的分庫分表中間件非常大的優(yōu)勢(shì);
    f、可透明使用后端數(shù)據(jù)節(jié)點(diǎn)的多種功能特性。比如全文索引,地理位置索引等。Spider的劣勢(shì):

    a、Spider的表不支持查詢緩存;
    b、Spider實(shí)例一致性物理備份困難。需要到每個(gè)數(shù)據(jù)節(jié)點(diǎn)單獨(dú)進(jìn)行物理備份,整個(gè)實(shí)例的一致性物理備份不好做;
    c、Spider本身是單點(diǎn)。可通過MySQL復(fù)制來實(shí)現(xiàn)高可用,但需為業(yè)務(wù)提供VIP實(shí)現(xiàn)Spider節(jié)點(diǎn)切換后的服務(wù)可用性;
    d、性能不如單MariaDB/MySQL實(shí)例。這是由于用戶請(qǐng)求多跨一層網(wǎng)絡(luò),性能上會(huì)有一些損耗。尤其是在跨分區(qū)、跨表查詢時(shí)。
    e、線上使用案例較少,功能穩(wěn)定性還未得到全面驗(yàn)證。比如筆者在某些部署模式下使用XA事務(wù)會(huì)報(bào)錯(cuò),在執(zhí)行DirectSQL時(shí)會(huì)導(dǎo)致mysqld crash。

    八、總結(jié)

    Spider的最大亮點(diǎn)是為MySQL的使用者提供分庫分表的中間件解決方案,同時(shí)在SQL語法上兼容MySQL。這得益于Spider作為MySQL的插拔式引擎而存在。Spider是一個(gè)proxy,其本身并沒有存儲(chǔ)數(shù)據(jù),因此上層的讀寫表請(qǐng)求需要轉(zhuǎn)換成SQL語句,重新路由到后端的數(shù)據(jù)節(jié)點(diǎn)。相比其它的中間件解決方案,Spider的查詢解析次數(shù)都是兩次,并沒有過多開銷。此外,Spider還針對(duì)聚集、排序等操作提供了MAP REDUCE的解決方案。
    Spider部署非常簡單,使用方便。可以使用在三類業(yè)務(wù)場(chǎng)景:一是業(yè)務(wù)存在多個(gè)數(shù)據(jù)庫實(shí)例,某些實(shí)例有訪問其他實(shí)例上數(shù)據(jù)的需求(比如做Join);二是分庫分表場(chǎng)景,比如業(yè)務(wù)存在超大表,或者業(yè)務(wù)的數(shù)據(jù)量一直在增加導(dǎo)致單數(shù)據(jù)庫實(shí)例無法容納,或者業(yè)務(wù)的并發(fā)請(qǐng)求非常多,單實(shí)例無法處理;三是作為Proxy,這個(gè)場(chǎng)景非常多,比如使用Spider實(shí)例作為堡壘機(jī),外部業(yè)務(wù)均訪問Spider節(jié)點(diǎn),不直接訪問后端數(shù)據(jù)庫服務(wù),提高網(wǎng)絡(luò)安全性。
    總之,從兼容性、性能上衡量,Spider是MySQL分庫分表一個(gè)不錯(cuò)的選項(xiàng)。

    九、參考

  • https://mariadb.com/kb/en/spider/
  • https://yq.aliyun.com/articles/80458
  • https://zhuanlan.zhihu.com/p/47418626
  • 總結(jié)

    以上是生活随笔為你收集整理的mysql递归查询所有上下节点_【转】MySQL之Spider存储引擎原理详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。