presto 转换静态catlog为动态catlog
近年来,基于hadoop的sql框架层出不穷,presto也是其中的一员.从2012年发展至今,依然保持年轻的活力(版本迭代依然很快),presto的相关介绍,我们就不赘述了,相信看官多对presto有或多或少的了解,详细的一些说明可以看官网(https://prestodb.io)的说明.
presto自身功能和思想富有先进性,虽然由于是内存计算,稳定性方面还有很大提升空间,但整体依然在adhoc方面有很好的竞争力.其中在catalog加载的方式上来说比较的固化,官方并没有做出动态的方案出来,导致在添加catalog后必须重启整个集群才可以将新添加的catalog数据源添加到presto中,这无疑在实际的生产环境中很不友好.尤其是在一些中台项目中,需要动态规划的东西非常多.这种模式的catalog添加方式显然不能满足我们的开发需要.
因此,在环境的加持下,对presto的加载catlog的方式的源码进行了改造,使其具有热动态添加的功能.我们采用了外部数据库作为他的catlog资源库,对其进行热加载
(1)添加restful API请求接口.
为了使框架本身具有添加catalog的功能,需要使其本身具有Api访问接口的方式来来对catalog的资源进行调整的功能
1.新增CatalogResource类来实现api的请求接口
2.新增TimiCatalogStoreConfig类来实现与数据库交互的持久层
3.新增TimiCatalogStore类来替换原本的catlog加载类
4.新增CatalogInfo类来实现对catalog Model信息的解析 #1 CatalogResource
@Path("/presto/catalog")
public class CatalogResource{
@GET
@Path("test")
public Response test()
{
return Response.ok("Hello world").build();
}
}
在ServerMainModule类中setup方法,最后一行添加jaxrsBinder(binder).bind(CatalogResource.class);将添加的请求类添加进来,然后启动主服务,并确认所开启的presto的请求接口地址,默认端口是:8080请求http://localhost:8080/presto/catalog/test
返回 "Hello world" 则表示restful API 接口添加成功.
#2 TimiCatalogStoreConfig 类中主要实现了读取数据库连接配置,以及具体执行的catalog执行动作,并使用jaxrsBinder(binder).bind(TimiCatalogStoreConfig.class);注入到项目启动的容器中.并将Announcer,disabledCatalogs,ConnectorManager注入到类中.具体实现
public class TimiCatalogStoreConfig { private final Announcer announcer;
private static final Logger log = Logger.get(TimiCatalogStoreConfig.class);
private final Set<String> disabledCatalogs;
private final ConnectorManager connectorManager;
public TimiCatalogStoreConfig(Announcer announcer,Set<String> disabledCatalogs,ConnectorManager connectorManager ) {
this.announcer = announcer;
this.disabledCatalogs = ImmutableSet.copyOf(disabledCatalogs);
this.connectorManager = connectorManager;
}
}
然后就是实现对catlog增删查改动作,并将操作的结构实现到ConnectorManager中,
首先将Server中的CatalogStore替换成我们自定义实现的TimiCatalogStore并注入相关类
@Inject
public TimiCatalogStore(ConnectorManager connectorManager, Announcer announcer, StaticCatalogStoreConfig config,TimiCatalogStoreConfig catalogStoreConfig) {
this(connectorManager,
announcer,
config.getCatalogConfigurationDir(),
firstNonNull(config.getDisabledCatalogs(), ImmutableList.of()),
catalogStoreConfig
);
}
然后实现loadCatalogs方法,首次调用的时候使用load();方法加载mysql中存储的所有catlog,然后使用ScheduledExecutorService定时的方式从mysql中提取有变化的catlog加载到presto的ConnectorManager中.
public static void updateConnectorIdAnnouncement(Announcer announcer, CatalogName connectorId)
{
//
// This code was copied from PrestoServer, and is a hack that should be removed when the connectorId property is removed
//
// get existing announcement
ServiceAnnouncement announcement = getPrestoAnnouncement(announcer.getServiceAnnouncements());
// update connectorIds property
Map<String, String> properties = new LinkedHashMap<>(announcement.getProperties());
String property = nullToEmpty(properties.get("connectorIds"));
Set<String> connectorIds = new LinkedHashSet<>(Splitter.on(',').trimResults().omitEmptyStrings().splitToList(property));
connectorIds.add(connectorId.toString());
properties.put("connectorIds", Joiner.on(',').join(connectorIds));
// update announcement
announcer.removeServiceAnnouncement(announcement.getId());
announcer.addServiceAnnouncement(serviceAnnouncement(announcement.getType()).addProperties(properties).build());
announcer.forceAnnounce();
}
在这里我们设定的1分钟从mysql库充更新一次catalog列表
scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
reload();
}
}, 60, 60, TimeUnit.SECONDS);
调用reload方法定时读取
public void reload() { try{
//获取最新的catalogs
Map<String, CatalogInfo> catalogInfos = catalogStoreConfig.load(); catalogInfos.forEach(
(key, catalogInfo) -> {
if (!catalogInfoMap.containsKey(key)) {
//相同--catlog
try {
System.out.println("添加数据源"+JSON.toJSONString(catalogInfo));
// log.info("添加数据源:{}",JSON.toJSONString(catalogInfos.get(key)));
CatalogName catalogName = loadCatalog(catalogInfo);
updateConnectorIdAnnouncement(announcer,catalogName);
} catch (Exception e) {
e.printStackTrace();
} } else {
//不同catlog
if (!JSON.toJSONString(catalogInfoMap.get(key)).equals(JSON.toJSONString(catalogInfo))){
connectorManager.dropConnection(catalogInfo.getCatalogName());
try {
System.out.println("添加数据源"+JSON.toJSONString(catalogInfo));
CatalogName catalogName = loadCatalog(catalogInfo);
updateConnectorIdAnnouncement(announcer,catalogName);
} catch (Exception e) {
e.printStackTrace();
}
} }
}
);
catalogInfoMap.putAll(catalogInfos); }catch (Exception e){
e.printStackTrace();
}
}
从mysql库中取出来的catlog信息和对现有的catlog进行对比,如果是不同的catlog就添加到presto中,重复的catlog不添加,删除的catlog就从现有的catlog管理器中删除,以此来达到动态添加catlog的动作,不需要重启presto服务器.
presto 转换静态catlog为动态catlog的更多相关文章
- Linux下Gcc生成和使用静态库和动态库详解(转)
一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...
- Linux下Gcc生成和使用静态库和动态库详解
参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库 ...
- Linux-Gcc生成和使用静态库和动态库详解
一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...
- C 高级编程3 静态库与动态库
http://blog.csdn.net/Lux_Veritas/article/details/11934083http://www.cnblogs.com/catch/p/3857964.html ...
- 黑马程序员:Java基础总结----静态代理模式&动态代理
黑马程序员:Java基础总结 静态代理模式&动态代理 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 静态代理模式 public class Ts { ...
- C++中的静态多态和动态多态
C++中的静态多态和动态多态 今天的C++已经是个多重泛型编程语言(multiparadigm programming lauguage),一个同时支持过程形式(procedural).面向对象形式( ...
- 静态NAT、动态NAT
静态NAT.动态NAT 实验拓扑: 实验目的:熟悉网络地址转换协议 掌握静态NAT 和动态NAT的配置 分析静态NAT 和动态NAT的区别 使用show命令来检查NAT的运行情况 实验要求:按拓扑图来 ...
- JSP页面的静态包含和动态包含
JSP中有两种包含:静态包含:<%@include file="被包含页面"%>和动态包含:<jsp:include page="被包含页面" ...
- face++静态库转为动态库
前言 苹果商店上架应用,有规定支持iOS8.0以上的iPA可执行文件的大小不能超过60M. face++提供过来的是静态库,会导致苹果上架的ipa的包增加1.5M左右.而刚好我们的APP包Mach-O ...
随机推荐
- shell编程之系统环境变量2
本课程是<Tony老师聊shell——变量>课程的延续,主要介绍Linux shell编程基础中的运算符.包括declare命令.数值运算方法和变量测试.首先在declare命令中介绍了数 ...
- 基于 Blazor 开发五子棋⚫⚪小游戏
今天是农历五月初五,端午节.在此,祝大家端午安康! 端午节是中华民族古老的传统节日之一.端午也称端五,端阳.此外,端午节还有许多别称,如:午日节.重五节.五月节.浴兰节.女儿节.天中节.地腊.诗人节. ...
- egret的WebView实现
需求 在egret中嵌入网页,类似 . 网上大概有两种思路吧,一种是直接在body里面加入iframe,如:[Egret]里使用iframe标签达到内嵌多个web界面;另一种就是通过模仿htmlinp ...
- html+css快速入门教程(6)
9 综合实例 仿百度云盘下载页面实战 10 表格 10.1 table table 为表格标签 可以让我们的表格在浏览器中显示 table 下面还有两个常用标签 tr 和 td tr表示一行 td表示 ...
- 019.Kubernetes二进制集群存储longhorn
一 Longhorn存储部署 1.1 Longhorn概述 Longhorn是用于Kubernetes的开源分布式块存储系统. 提示:更多介绍参考:https://github.com/longhor ...
- Java多线程之synchronized详解
目录 synchronized简介 同步的原理 对象头与锁的实现 锁的优化与升级 Monitor Record 锁的对比 synchronized简介 synchronized关键字,一般称之为&qu ...
- 02.RabbitMQ整合springboot简单使用
1.添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- 状压DP之集合选数
题目 [HNOI2012]集合选数 <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不 ...
- 如何使用CSS3 调节 tab的高度
包含大量代码的网页(比如文档或教程)在样式上面对着无法回避的挑战.我们通常使用 <pre> 和 <code> 元素来显示代码,它们具有浏览器所赋予的默认样式.这些默认样式往往是 ...
- SpringBoot系列之前后端接口安全技术JWT
@ 目录 1. 什么是JWT? 2. JWT令牌结构怎么样? 2.1 标头(Header) 2.2 有效载荷(Playload) 2.3 签名(Signature) 3. JWT原理简单介绍 4. J ...