设置主机名启动 IoTDB 可在不修改配置情况下,在不同环境运行 IoTDB 并实现多次部署。
01
前言
IoTDB 在配置启动时有两种方式:
1. 通过设置 HostName(主机名)的方式来启动 IoTDB(推荐方式);
2. 通过设置 IP 的方式来启动 IoTDB。
因为设置主机名要修改 hosts 文件多一步操作,所以可能有的用户更习惯于设置 IP 的方式来启动 IoTDB。本文将结合一个典型场景:集群迁移,来解答这些用户可能会产生的困惑:
什么是 HostName(主机名)?和 IP 的关系是怎样的?
IoTDB 启动为什么推荐使用主机名?使用主机名相较于 IP 会带来什么样的好处?
02
集群迁移背景
集群迁移:在部署 IoTDB 后,可能会遇到某些情况导致需要将部分/全部的 IoTDB 节点从旧机器迁移到新机器上。
IoTDB 迁移影响最大的是网络,因为几乎所有的集群在启动时都会更改:
cn/dn_internal_address 参数(IoTDB 内部通信需要使用的网络地址);
cn/dn_seed_config_node 参数(seed_config_node 的网络地址。初次启动时使用,所有的节点都必须向其发送注册信息,以此来表示自己要加入该集群);
dn_rpc_address参数(Session 和 Cli 连接 DataNode 使用的网络地址)。
而这三个参数都是启动后不可修改的参数。
如果你尝试去关闭一个 ConfigNode/DataNode,修改 cn/dn_internal_address 并重新启动,是会报出如下错误的:
这主要是因为对于一个 IoTDB 集群来说,集群间的节点 RPC 通信需要通过网络,因此在 IoTDB 内部维护了一张节点编号->网络地址的表。节点重启并不会改变该节点的编号,但是如果更改了网络地址,那么会和已经存在的表冲突,进而导致启动的失败。
03
主机名与 IP
(1)IoTDB 用 IP 来做什么?
如图所示,IoTDB 节点间通信是通过 thrift RPC 来实现的,在 thrift 的传输层(Transport)时使用 Socket,Socket 的建立需要 IP 与 port。
(2)IP 、域名、主机名、DNS
IP:一个 32 位的二进制数(IPv4)用于在一个在网络通信中用于确定一台主机。但是其可读性却比较差,并且无实际含义,不利于记忆。因此设计出了主机名、域名以及域名解析系统(DNS)来解决这一问题。
主机名:识别网络上的主机。
域名:识别网站。主机名是域名的最前部分(例如 www.timecho.com 是域名,其中 www 是主机名)。
无论是主机名还是域名,都是为了方便人去访问网络上的其他设备,都可以理解为 IP 地址的别名。
DNS:是将域名和主机名解析成对应 IP 地址的服务器。
举个例子:如果没有 DNS,你要访问天谋科技的主页需要通过在导航栏输入 123.56.10.29(IP),而通过 DNS 只需要输入 www.timecho.com (域名)即可访问。域名将通过 DNS 解析成对应的 IP。如果有一天可能由于某些原因更换了官网的 IP 地址,你仍然可以通过域名访问天谋科技的主页,因为 DNS 会将其解析成新的 IP 地址。
一个 DNS 的解析过程如下图所示,先尝试进行本地的解析工作,之后再由本地 DNS 服务器去迭代的解析。本地解析优先级会高于 DNS 解析,这样会加快整体的解析过程,在本地解析的过程中,会去查看 hosts 文件。
(3)hosts 文件
hosts 文件:保存主机名与 IP 的映射关系。
Windows 系统,hosts 文件位置:
C:\Windows\System32\drivers\etc\hosts
Linux 系统,hosts 文件位置:
/etc/hosts
04
主机名启动 IoTDB
与 IP 启动 IoTDB 的区别
我们可以很容易理解设置 IP 地址可以让 Socket 建立,进而使得 IoTDB 节点间能够通信,进而启动 IoTDB。
(1)主机名为什么能启动 IoTDB 呢?
前文已经说过,IoTDB 启动后会维护节点编号->网络地址的表。之所以用主机名也能表示网络地址,主要是 java.net 中 InetAddress 类支持解析主机名。如下所示,调用 NameService 就会通过 DNS 解析(用到 hosts 文件)的方式得到其 IP 地址。
/etc/hostsprivate static InetAddress[] getAddressesFromNameService(String host, InetAddress reqAddr) throws UnknownHostException {... ...if ((addresses = checkLookupTable(host)) == null) { // 是否正在解析该host ?等待try {for (NameService nameService : nameServices) {try {addresses = nameService.lookupAllHostAddr(host); // 向该域名服务请求域名解析success = true;break; // 只要有一个域名服务成功解析host则退出循环} catch (UnknownHostException uhe) {// 1. 若host = localhost,则addresses = [loopbackAdress] & 退出循环// 2. 否则准备抛异常(addresses = unknown_array & success = false & 记录uhe) & 继续循环 ... ...}}// 若reqAddr不为空 && addresses中存在与reqAddr相等的InetAddress,则将该InetAddress挪到第一个位置 ... ...cacheAddresses(host, addresses, success); // 缓存记录// 域名解析失败则抛异常uhe ... ...} finally {updateLookupTable(host); // 唤醒所有等待解析该host的线程 }}return addresses;
}
这样对于 IoTDB 来说,表保留 IP 地址或者主机名都能够成功的建立网络连接。
(2)两种启动方式的区别
假设我们启动了一个 1C1D 的 IoTDB。
IP 启动
0 号节点是 ConfigNode,1 号节点是 DataNode。各自有一张表记录节点编号->网络地址。通过 IP 来使 Socket 连接,达成通信。
主机名启动
同样 0 号节点是 ConfigNode,1 号节点是 DataNode。各自有一张表记录节点编号->网络地址。Socket 通过主机名访问 hosts 文件解析出真实的 IP 地址后建立 Socket 连接。
小结
正所谓遇到不好解决的问题的时候,多加一层就可以解决。多加的这层就是主机名的解析,通过这层解析,做到在不修改 IoTDB 内部网络通信表的情况下,访问不同的 IP 地址(就像前文中访问 www.timecho.com 的例子一样)。
05
集群迁移步骤
接下来通过一个实际的集群迁移步骤来说明两种启动方式在集群迁移过程中的区别。
(1)集群迁移(通过 HostName 启动 IoTDB)
如果通过 HostName 启动 IoTDB,只需要在新的机器上修改 hosts 文件中 域名 对应的 IP 地址,启动 IoTDB 即可,详细步骤如下:
1. 假设已经通过 1.3.x 集群版 IoTDB 安装部署了一个 3C3D 的 IoTDB 集群,其 hosts 文件内容如下:
(部署教程可见:
https://timecho.com/docs/zh/UserGuide/latest/QuickStart/ClusterQuickStart.html)
2. 启动 3C3D 集群,这里通过 IP 地址连接(也可以通过 -h iotdb 2),验证我们所连接集群的 IP 地址。
3. 向三个节点分别插入数据,并验证此时的数据是可以查询的。
4. 关闭 3C3D 集群,并将他们上传至新的机器上,新机器的 hosts 文件内容如下:
5. 在新机器上启动 3C3D 集群,这里通过 IP 地址连接(也可以通过 -h iotdb 2),验证我们所连接集群的 IP 地址。
6. 查询 region 和数据,均可查,说明集群迁移成功。
(2)集群迁移(通过 IP 启动 IoTDB)
如果通过 IP 地址启动了 IoTDB 集群,由于网络参数项不可更改,想迁移某个节点只能通过:
1. 在旧机器上 remove 该节点(如果该节点含有大量的数据,所有的数据都需要迁移进别的节点);
2. 在新机器上启动一个全新的节点(此时所有的负载均衡均需要重新计算)。
如果是迁移整个集群,就得在所有的节点上执行上述的操作,整个操作非常的繁琐并且浪费了大量的资源进行节点间的数据迁移。并且在上述迁移 3C3D 集群的例子中,你甚至无法通过该方式迁移,因为迁移前后的两个集群网络上不通。此时只能将 3C3D 的所有数据信息(tsfile)分别 load 进新的集群。做一个数据迁移,而非集群迁移。
06
总结
希望读者能通过这篇文章能理解网络连接在 IoTDB 启动过程中的作用,能清楚设置主机名启动和设置 IP 启动两种方式在 IoTDB 建立网络连接时的联系和区别。
通过设置主机名启动实现了不修改 IoTDB 的配置,能在不同环境上运行相同的 IoTDB,不但可以直接将整个 IoTDB 打包多次部署,也可以在遇到问题时将打包发给开发人员调试问题。
强力推荐所有的 IoTDB 用户都通过设置主机名的方式来启动 IoTDB!
强力推荐所有的 IoTDB 用户都通过设置主机名的方式来启动 IoTDB!
强力推荐所有的 IoTDB 用户都通过设置主机名的方式来启动 IoTDB!
重要的事情说三遍。