1. 程式人生 > >TableStore: 海量結構化資料分層儲存方案

TableStore: 海量結構化資料分層儲存方案

前言

表格儲存是阿里雲自研分散式儲存系統,可以用來儲存海量結構化、半結構化的資料。表格儲存支援高效能和容量型兩種例項型別。高效能使用SSD的儲存介質,針對讀多寫多的場景都有較好的訪問延時。容量型使用的是SSD和SATA混合的儲存介質。對寫多的場景,效能接近高效能,讀方面,如果遇到冷資料產生讀SATA盤的話,延時會比高效能上漲一個量級。在海量資料儲存場景下,例如時序場景,我們會希望最新的資料可以支援高效能查詢,較早的資料的讀寫頻次都會低很多。這時候一個基於表格儲存高效能和容量型儲存分層的需求就產生了。

方案細節

表格儲存近期對外正式釋出的全增量一體的通道服務(參考文件),通道服務基於表格儲存資料介面之上的全增量一體化服務。通道服務為使用者提供了增量、全量、增量加全量三種類型的分散式資料實時消費通道。有了通道服務,我們可以很方便的構建從高效能例項下的表到容量型表之間的實時資料同步,進而可以在高效能表上使用表格儲存的特性資料生命週期(

參考文件),根據業務需求設定一個合理的TTL。

總體來說就可以構建一個如下圖所示的架構:

整個資料的流動過程如下:

  1. 業務寫入端直接寫入高效能例項
  2. 高效能例項中的資料通過通道服務同步至容量型
  3. 高效能例項中的老資料自動過期,減少儲存量佔用
  4. 使用者查詢請求根據時序查詢條件,判斷是否是近期資料

    1. 近期資料查詢進入高效能,毫秒級別返回
    2. 較早資料查詢進入容量型,幾十毫秒後返回

程式碼和操作流程:

在高效能例項上根據業務主鍵需求建立資料表,並設定合理的資料TTL,然後在容量型下建立相同的schema的表用來持久化儲存所有資料。

然後在通道頁面建立一個全增量型別的通道:

通過控制檯可以簡單清晰的檢視到同步的狀態,併發,進度等資訊:

下面貼一下通過Tunnel進行復制同樣schema表TableStore表的Sample程式碼:

func main () {
    //高效能例項的資訊
  tunnelClient := tunnel.NewTunnelClient("", "", "", "")
  //容量型例項的資訊
    client := tablestore.NewClient("", "", "", "")

    //配置callback到SimpleProcessFactory,配置消費端TunnelWorkerConfig
    workConfig := &tunnel.TunnelWorkerConfig{
        ProcessorFactory: &tunnel.SimpleProcessFactory{
            ProcessFunc: replicateDataFunc,
            CustomValue: client,
        },
    }

    //使用TunnelDaemon持續消費指定tunnel
    daemon := tunnel.NewTunnelDaemon(tunnelClient, "", workConfig)
    err := daemon.Run()
    if err != nil {
        fmt.Println("failed to start tunnel daemon with error:", err)
    }
}

func replicateDataFunc(ctx *tunnel.ChannelContext, records []*tunnel.Record) error {
    client := ctx.CustomValue.(*tablestore.TableStoreClient)
    fmt.Println(client)
    for _, rec := range records {
        fmt.Println("tunnel record detail:", rec.String())
        updateRowRequest := new(tablestore.UpdateRowRequest)
        updateRowRequest.UpdateRowChange = new(tablestore.UpdateRowChange)
        updateRowRequest.UpdateRowChange.TableName = "coldtable"
        updateRowRequest.UpdateRowChange.PrimaryKey = new(tablestore.PrimaryKey)
        updateRowRequest.UpdateRowChange.SetCondition(tablestore.RowExistenceExpectation_IGNORE)
        for _, pk := range rec.PrimaryKey.PrimaryKeys {
            updateRowRequest.UpdateRowChange.PrimaryKey.AddPrimaryKeyColumn(pk.ColumnName, pk.Value)
        }
        for _, col := range rec.Columns {
            if col.Type == tunnel.RCT_Put {
                updateRowRequest.UpdateRowChange.PutColumn(*col.Name, col.Value)
            } else if col.Type == tunnel.RCT_DeleteOneVersion {
                updateRowRequest.UpdateRowChange.DeleteColumnWithTimestamp(*col.Name, *col.Timestamp)
            } else {
                updateRowRequest.UpdateRowChange.DeleteColumn(*col.Name)
            }
        }

        _, err := client.UpdateRow(updateRowRequest)
        if err != nil {
            fmt.Println("hit error when put record to cold data", err)
        }
    }
    fmt.Println("a round of records consumption finished")
    return nil
}

總結

通過通道服務,儲存在表格儲存中的結構化,半結構化資料可以實時流出,進行加工,萃取,計算或進行同步。如果是想進一步降低冷資料的儲存成本,可以參考這篇文章把表格儲存的資料備份到OSS歸檔儲存。

作者:宇珩

原文連結

本文為雲棲社群原創內容,未經允許