表格存储是阿里云自研分布式存储系统,可以用来存储海量结构化、半结构化的数据。表格存储支持高性能和容量型两种实例类型。高性能使用SSD的存储介质,针对读多写多的场景都有较好的访问延时。容量型使用的是SSD和SATA混合的存储介质。对写多的场景,性能接近高性能,读方面,如果遇到冷数据产生读SATA盘的话,延时会比高性能上涨一个量级。在海量数据存储场景下,例如时序场景,我们会希望最新的数据可以支持高性能查询,较早的数据的读写频次都会低很多。这时候一个基于表格存储高性能和容量型存储分层的需求就产生了。
方案细节表格存储近期对外正式发布的全增量一体的通道服务(参考文档 https://help.aliyun.com/document_detail/102489.html),通道服务基于表格存储数据接口之上的全增量一体化服务。通道服务为用户提供了增量、全量、增量加全量三种类型的分布式数据实时消费通道。有了通道服务,我们可以很方便的构建从高性能实例下的表到容量型表之间的实时数据同步,进而可以在高性能表上使用表格存储的特性数据生命周期(参考文档 https://help.aliyun.com/document_detail/27280.html),根据业务需求设置一个合理的TTL。
总体来说就可以构建一个如下图所示的架构:
整个数据的流动过程如下:
业务写入端直接写入高性能实例高性能实例中的数据通过通道服务同步至容量型高性能实例中的老数据自动过期,减少存储量占用用户查询请求根据时序查询条件,判断是否是近期数据近期数据查询进入高性能,毫秒级别返回较早数据查询进入容量型,几十毫秒后返回代码和操作流程:
在高性能实例上根据业务主键需求创建数据表,并设置合理的数据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归档存储。
作者:宇珩
原文链接:https://yq.aliyun.com/articles/692520?utm_content=g_1000061183
海量数据存储有哪些方式与方法
杉岩海量对象存储MOS,针对海量非结构化数据存储的最优化解决方案,采用去中心化、分布式技术架构,支持百亿级文件及EB级容量存储,
具备高效的数据检索、智能化标签和分析能力,轻松应对大数据和云时代的存储挑战,为企业发展提供智能决策。
1、容量可线性扩展,单名字空间达EB级
SandStone MOS可在单一名字空间下实现海量数据存储,支持业务无感知的存储服务器横向扩容,为爆炸式增长的视频、音频、图片、文档等不同类型的非结构化数据提供完美的存储方案,规避传统NAS存储的单一目录或文件系统存储空间无法弹性扩展难题
2、海量小文件存储,百亿级文件高效访问
SandStone MOS基于完全分布式的数据和元数据存储架构,为海量小文件存储而生,将企业级NAS存储的千万文件量级提升至互联网规模的百亿级别,帮助企业从容应对几何级增长的海量小文件挑战。
3、中心灵活部署,容灾汇聚分发更便捷
SandStone MOS支持多数据中心灵活部署,为企业数据容灾、容灾自动切换、多分支机构、数据就近访问等场景提供可自定义的灵活解决方案,帮助企业实现跨地域多活容灾、数据流转、就近读写等,助力业务高速发展。
4、支持大数据和AI,统一数据存储和分析
SandStone MOS内置文件智能化处理引擎,实现包括语音识别、图片OCR识别、文件格式转换等批量处理功能,结合标签检索能力还可实现语音、证件照片检索,从而帮助企业更好地管理非结构化数据。同时,SandStone MOS还支持与Hadoop、Spark等大数据分析平台对接,一套存储即可满足企业数据存储、管理和挖掘的需求。
Bigtable---分布式的结构化数据存储系统
sinaBigtable 是一个分布式的结构化数据存储系统,它被设计用来处理海量数据:通常是分布在数千台普通服务器上的PB 级的数据。Google 的很多项目使用Bigtable 存储数据,包括Web 索引、GoogleEarth、Google Finance。这些应用对Bigtable 提出的要求差异非常大,无论是在数据量上(从URL到网页到卫星图像)还是在响应速度上(从后端的批量处理到实时数据服务)。
Bigtable 已经实现了下面的几个目标:适用性广泛、可扩展、高性能和高可用性,Bigtable 是一个稀疏的、分布式的、持久化存储的多维度排序Map。
图一:一个存储Web 网页的例子的表的片断。行名是一个反向URL。contents 列族存放的是网页的内容,anchor 列族存放引用该网页的锚链接文本(alex 注:如果不知道HTML 的Anchor,请Google一把)。CNN 的主页被Sports Illustrater和MY-look 的主页引用,因此该行包含了名为“anchor:cnnsi.com”和“anchhor:my.look.ca”的列。每个锚链接只有一个版本(alex 注:注意时间戳标识了列的版本,t9 和t8 分别标识了两个锚链接的版本);而contents 列则有三个版本,分别由时间戳t3,t5,和t6 标识。
行
Bigtable 通过行关键字的字典顺序来组织数据。表中的每个行都可以动态分区。每个分区叫做一个”Tablet”,Tablet 是数据分布和负载均衡调整的最小单位。
列族
Webtable 有个列族language,language 列族用来存放撰写网页的语言。
我们在language 列族中只使用一个列关键字,用来存放每个网页的语言标识ID。Webtable 中另一个有用的列族是anchor;这个列族的每一个列关键字代表一个锚链接,如图一所示。Anchor 列族的限定词是引用该网页的站点名;Anchor 列族每列的数据项存放的是链接文本。访问控制、磁盘和内存的使用统计都是在列族层面进行的。
时间戳
不同版本的数据通过时间戳来索引。Bigtable 时间戳的类型是64 位整型。
Bigtable 可以给时间戳赋值,用来表示精确到毫秒的“实时”时间;用户程序也可以给时间戳赋值。如果应用程序需要避免数据版本冲突,那么它必须自己生成具有唯一性的时间戳。数据项中,不同版本的数据按照时间戳倒序排序,即最新的数据排在最前面。为了减轻多个版本数据的管理负担,我们对每一个列族配有两个设置参数, Bigtable 通过这两个参数可以对废弃版本的数据自动进行垃圾收集。用户可以指定只保存最后n 个版本的数据,或者只保存“足够新”的版本的数据(比如,只保存最近7 天的内容写入的数据)。
Bigtable支持的其他特性
1、Bigtable 支持单行上的事务处理,利用这个功能,用户可以对存储在一个行关键字下的数据进行原子性的读-更新-写操作。
2、Bigtable 允许把数据项用做整数计数器。
3、Bigtable 允许用户在服务器的地址空间内执行脚本程序
4、Bigtable 可以和MapReduce一起使用,MapReduce 是Google 开发的大规模并行计算框架。我们已经开发了一些Wrapper 类,通过使用这些Wrapper 类,Bigtable 可以作为MapReduce 框架的输入和输出。
Bigtable依赖于google的几项技术。用GFS来存储日志和数据文件;按SSTable文件格式存储数据;用Chubby管理元数据:
Bigtable是建立在其它的几个Google基础构件上的。BigTable 使用Google 的分布式文件系统(GFS)存储日志文件和数据文件。BigTable 集群通常运行在一个共享的机器池中,池中的机器还会运行其它的各种各样的分布式应用程序,BigTable 的进程经常要和其它应用的进程共享机器。BigTable 依赖集群管理系统来调度任务、管理共享的机器上的资源、处理机器的故障、以及监视机器的状态。
BigTable 内部存储数据的文件是Google SSTable 格式的。SSTable 是一个持久化的、排序的、不可更改的Map 结构,而Map 是一个key-value 映射的数据结构,key 和value 的值都是任意的Byte串,从内部看,SSTable 是一系列的数据块(通常每个块的大小是64KB,这个大小是可以配置的)。。SSTable 使用块索引(通常存储在SSTable 的最后)来定位数据块;在打开SSTable的时候,索引被加载到内存。每次查找都可以通过一次磁盘搜索完成:首先使用二分查找法在内存中的索引里找到数据块的位置,然后再从硬盘读取相应的数据块。也可以选择把整个SSTable 都放在内存中,这样就不必访问硬盘了。
BigTable 还依赖一个高可用的、序列化的分布式锁服务组件,叫做Chubby。Chubby有五个活跃副本,同时只有一个主副本提供服务,副本之间用Paxos算法维持一致性,Chubby提供了一个命名空间(包括一些目录和文件),每个目录和文件就是一个锁,Chubby的客户端必须和Chubby保持会话,客户端的会话若过期则会丢失所有的锁。
Bigtable 包括了三个主要的组件:链接到客户程序中的库、一个Master主服务器和多个Tablet片 服务器。
Bigtable会将表(table)进行分片,片(tablet)的大小维持在100-200MB范围,一旦超出范围就将分裂成更小的片,或者合并成更大的片。每个片服务器负责一定量的片,处理对其片的读写请求,以及片的分裂或合并。片服务器可以根据负载随时添加和删除。这里片服务器并不真实存储数据,而相当于一个连接Bigtable和GFS的代理,客户端的一些数据操作都通过片服务器代理间接访问GFS。主服务器负责将片分配给片服务器,监控片服务器的添加和删除,平衡片服务器的负载,处理表和列族的创建等。注意,主服务器不存储任何片,不提供任何数据服务,也不提供片的定位信息。
客户端需要读写数据时,直接与片服务器联系。因为客户端并不需要从主服务器获取片的位置信息,所以大多数客户端从来不需要访问主服务器,主服务器的负载一般很轻。
Master 服务器主要负责以下工作:为Tablet 服务器分配Tablets、检测新加入的或者过期失效的Table 服务器、对Tablet 服务器进行负载均衡、以及对保存在GFS 上的文件进行垃圾收集。除此之外,它还处理对模式的相关修改操作,例如建立表和列族。
我们使用一个三层的、类似B 树的结构存储Tablet 的位置信息。
第一层是一个存储在Chubby 中的文件,它包含了Root Tablet 的位置信息。这个Chubby文件属于Chubby服务的一部分,一旦Chubby不可用,就意味着丢失了root tablet的位置,整个Bigtable也就不可用了。
第二层是root tablet。root tablet其实是元数据表(METADATA table)的第一个分片,它保存着元数据表其它片的位置。root tablet很特别,为了保证树的深度不变,root tablet从不分裂。
第三层是其它的元数据片,它们和root tablet一起组成完整的元数据表。每个元数据片都包含了许多用户片的位置信息。
片的数据最终还是写到GFS里的,片在GFS里的物理形态就是若干个SSTable文件。下图展示了读写操作基本情况。
BigTable和GFS的关系
集群包括主服务器和片服务器,主服务器负责将片分配给片服务器,而具体的数据服务则全权由片服务器负责。但是不要误以为片服务器真的存储了数据(除了内存中memtable的数据),数据的真实位置只有GFS才知道,主服务器将片分配给片服务器的意思应该是,片服务器获取了片的所有SSTable文件名,片服务器通过一些索引机制可以知道所需要的数据在哪个SSTable文件,然后从GFS中读取SSTable文件的数据,这个SSTable文件可能分布在好几台chunkserver上。
一个简化的Bigtable结构图:
结构图以Webtable表为例,表中存储了网易、百度和豆瓣的几个网页。当我们想查找百度贴吧昨天的网页内容,可以向Bigtable发出查询Webtable表的(com.baidu.tieba, contents:, yesterday)。
假设客户端没有该缓存,那么Bigtable访问root tablet的片服务器,希望得到该网页所属的片的位置信息在哪个元数据片中。使用 METADATA.Webtable.com.baidu.tieba 为行键在root tablet中查找,定位到最后一个比它大的是 METADATA.Webtable.com.baidu.www ,于是确定需要的就是元数据表的片A。访问片A的片服务器,继续查找 Webtable.com.baidu.tieba ,定位到 Webtable.com.baidu.www 是比它大的,确定需要的是Webtable表的片B。访问片B的片服务器,获得数据。
这里需要注意的是,每个片实际都由若干SSTable文件和memtable组成,而且这些SSTable和memtable都是已排序的。这就导致查找片B时,可能需要将所有SSTable和memtable都查找一遍;另外客户端应该不会直接从元数据表获得SSTable的文件名,而只是获得片属于片服务器的信息,通过片服务器为代理访问SSTable。