TableStore: 海量結構化數據分層存儲方案

前言

表格存儲是阿里雲自研分佈式存儲系統,能夠用來存儲海量結構化、半結構化的數據。表格存儲支持高性能和容量型兩種實例類型。高性能使用SSD的存儲介質,針對讀多寫多的場景都有較好的訪問延時。容量型使用的是SSD和SATA混合的存儲介質。對寫多的場景,性能接近高性能,讀方面,若是遇到冷數據產生讀SATA盤的話,延時會比高性能上漲一個量級。在海量數據存儲場景下,例如時序場景,咱們會但願最新的數據能夠支持高性能查詢,較早的數據的讀寫頻次都會低不少。這時候一個基於表格存儲高性能和容量型存儲分層的需求就產生了。架構

方案細節

表格存儲近期對外正式發佈的全增量一體的通道服務,通道服務基於表格存儲數據接口之上的全增量一體化服務。通道服務爲用戶提供了增量、全量、增量加全量三種類型的分佈式數據實時消費通道。有了通道服務,咱們能夠很方便的構建從高性能實例下的表到容量型表之間的實時數據同步,進而能夠在高性能表上使用表格存儲的特性數據生命週期,根據業務需求設置一個合理的TTL。
整體來講就能夠構建一個以下圖所示的架構:


整個數據的流動過程以下:併發

  1. 業務寫入端直接寫入高性能實例
  2. 高性能實例中的數據經過通道服務同步至容量型
  3. 高性能實例中的老數據自動過時,減小存儲量佔用
  4. 用戶查詢請求根據時序查詢條件,判斷是不是近期數據分佈式

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

代碼和操做流程:

在高性能實例上根據業務主鍵需求建立數據表,並設置合理的數據TTL,而後在容量型下建立相同的schema的表用來持久化存儲全部數據。
性能

而後在通道頁面建立一個全增量類型的通道:
阿里雲

經過控制檯能夠簡單清晰的查看到同步的狀態,併發,進度等信息:


下面貼一下經過Tunnel進行復制一樣schema表TableStore表的Sample代碼:spa

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
}

總結code

經過通道服務,存儲在表格存儲中的結構化,半結構化數據能夠實時流出,進行加工,萃取,計算或進行同步。若是是想進一步下降冷數據的存儲成本,能夠參考這篇文章把表格存儲的數據備份到OSS歸檔存儲。  blog


原文連接
本文爲雲棲社區原創內容,未經容許不得轉載。接口

相關文章
相關標籤/搜索