接上一篇, 补充几个小问题
0. 计算相关序列化
presto内部使用jackson-core进行序列化. 由于是分布式环境, 因此需要将每个split要计算的元数据序列化后传输到各个worker节点. 开发时需要注意凡是要被传输到其他节点执行的信息都要序列化.
1. ConnectorTableHandle
, ColumnHandle
和 ConnectorTableMetadata
, ColumnMetadata
有什么区别?
-
XXXMetadata
是用来表示table的元数据的, 包括 column_name 和 type, 信息是catalog 不相关的 -
XXXHandle
是用来表示特定的catalog的table/column的信息, 包含column name 和数据类型. 简单来说,XXXHandle
就是XXXMetadata
+connectorId
. 最必需的信息是connectorId. 虽然XXXHandle
默认是一个Marker Interface
(就是没有任何一个方法), 但该数据是会被序列化后传输到worker节点的, 因此connectorId 这个属性是绕不过的. 参见下面connectorId
是干嘛呢
2. connectorId
是干嘛的
presto中数据的组织方式是三层: catalog-->schema --> table. 一个catalog 只能是一种connector, 通过配置文件中connector.name
指定, 例如hive的一个catalog的配置:
connector.name=hive-cdh5
hive.metastore.uri=thrift://localhost:10000
hive.config.resources=/home/ec2-user/presto/etc/core-site.xml,/home/ec2-user/presto/etc/hdfs-site.xml
hive.s3.pin-client-to-current-region=true
而catalog 的名称就是配置文件的名称(去除后缀). 在Connector中, connectorId就是这个对应的catalog的名称. XXXHandle
中connectorId的作用就是worker节点中根据这个 ID 查找对应的配置从而执行计算
3. ConnectorSplit
很简单, 就是coordinator 计算split后要将各个任务序列化后传输给各个worker节点计算. 因此实现的时候仅仅把分块计算所需的任何数据都扔到这个实现类里面, 搞成可序列化即可.
4. Guice 不了解怎么办?
看过presto源代码的都知道presto是使用Guice做为依赖注入框架, 不了解怎么办? 那就不用. presto 使用了java的Service Provider Interfaces 组织connector, 自己的connector 不使用guice 没有任何关系.
5. Presto如何初始化connector?
Service Provider Interfaces 有规范的, 简单讲就是在src/main/resources/META-INF/services/
中添加一个名为 com.facebook.presto.spi.Plugin
的文件, 里面写你的connector中实现了com.facebook.presto.spi.Plugin
这个接口的类
总结
在QCon2015 中 开源大数据在Facebook与Dropbox的实践 得知, Presto 最初的原型是一个工程师一个月做出来的, 后面经过历代版本的优化至今. 代码质量非常高, 就是用了一个估计是几个哥们儿自己写的框架airlift
, 文档比较少. 但正是这种connector的结构, 可以让我们很容易构建一个可以让异构数据源之间轻松 join 的数据平台, 减少数据接入的工作.
-- EOF --
网友评论