├── .gitignore ├── README.md ├── local ├── cluster.sh ├── config.sh └── delete.sh └── remote ├── config.sh ├── deploy.sh ├── kill.sh ├── pull.sh └── update.py /.gitignore: -------------------------------------------------------------------------------- 1 | remote/result/ 2 | remote/cluster-0.13.0-SNAPSHOT.tar 3 | remote/cluster-0.13.0-SNAPSHOT/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 用途 2 | 本 repo 旨在容器化管理集群之前为分布式 IoTDB 伪分布式和分布式的部署测试提供方便。 3 | 4 | ## 功能介绍 5 | 6 | ### 伪分布式模式 7 | 8 | #### 前提条件 9 | * 打包 cluster 模块。 10 | * 配置 local 目录下的 config 文件。 11 | 12 | #### 使用方式 13 | * 使用`sh cluster.sh`一键复制多个包并处理端口冲突,然后去对应的三个目录下分别开启 shell 运行 `sh sbin/start-node.sh` (Linux/MacOS) 或直接点击`start-node.bat` (Windows) 启动集群的一个节点,默认为 3 节点 3 副本的伪分布式集群。 14 | * 使用`sh delete.sh`清除所有的数据文件和日志以支持数据清零重新启动。 15 | 16 | 注:启动时需要保证 9003-9008, 40010-40015, 6667-6669, 31999-32001 端口没有其他进程正在使用。 17 | 18 | ### 分布式模式 19 | 20 | #### 前提条件 21 | * 打包 cluster 模块。 22 | * 配置 remote 目录下的 config 文件,比如 cluster 模块的打包路径,服务器 ip,服务器用户名,更改参数等等。 23 | * 本机可免密登陆 config 文件服务器参数中定义的所有测试服务器,可参考此[博客](https://blog.csdn.net/jeikerxiao/article/details/84105529)配置免密登陆。 24 | * Python3。 25 | 26 | #### 使用方式 27 | 28 | * 使用 `sh deploy.sh` 一键部署启动集群,默认会向远程推包,此外也可以通过 `sh deploy.sh np` 来取消推包只启动集群(建立在远程已有包的前提下)。 29 | * 使用 `sh pull.sh` 一键拉取各个节点的日志到本地分析。 30 | * 最后用 `sh kill.sh` 一键 kill 掉测试服务器上的分布式进程释放资源。 31 | 32 | 注: 33 | 在 iotdb 的主目录用 maven 编译 cluster 的命令: 34 | ``` 35 | mvn clean package -pl cluster -am -Dmaven.test.skip=true 36 | ``` -------------------------------------------------------------------------------- /local/cluster.sh: -------------------------------------------------------------------------------- 1 | source ./config.sh 2 | 3 | #删除所有数据并重新拷贝 4 | rm -rf $snapshotPath/data $snapshotPath/logs 5 | rm -rf ${snapshotPath}1 ${snapshotPath}2 ${snapshotPath}3 6 | cp -rf $snapshotPath ${snapshotPath}1 7 | cp -rf $snapshotPath ${snapshotPath}2 8 | cp -rf $snapshotPath ${snapshotPath}3 9 | 10 | ##统一 seeds_node 11 | sed -i -e 's/^seed_nodes=127.0.0.1:9003$/seed_nodes=127.0.0.1:9003,127.0.0.1:9005,127.0.0.1:9007/g' ${snapshotPath}/conf/iotdb-cluster.properties 12 | sed -i -e 's/^seed_nodes=127.0.0.1:9003$/seed_nodes=127.0.0.1:9003,127.0.0.1:9005,127.0.0.1:9007/g' ${snapshotPath}1/conf/iotdb-cluster.properties 13 | sed -i -e 's/^seed_nodes=127.0.0.1:9003$/seed_nodes=127.0.0.1:9003,127.0.0.1:9005,127.0.0.1:9007/g' ${snapshotPath}2/conf/iotdb-cluster.properties 14 | 15 | 16 | ##打开 open_server_rpc_port 17 | # sed -i -e 's/^open_server_rpc_port=false$/open_server_rpc_port=true/g' ${snapshotPath}/conf/iotdb-cluster.properties 18 | # sed -i -e 's/^open_server_rpc_port=false$/open_server_rpc_port=true/g' ${snapshotPath}1/conf/iotdb-cluster.properties 19 | # sed -i -e 's/^open_server_rpc_port=false$/open_server_rpc_port=true/g' ${snapshotPath}2/conf/iotdb-cluster.properties 20 | # sed -i -e 's/^open_server_rpc_port=false$/open_server_rpc_port=true/g' ${snapshotPath}3/conf/iotdb-cluster.properties 21 | 22 | # #统一副本数 23 | # sed -i -e 's/^default_replica_num=1$/default_replica_num=3/g' ${snapshotPath}/conf/iotdb-cluster.properties 24 | # sed -i -e 's/^default_replica_num=1$/default_replica_num=3/g' ${snapshotPath}1/conf/iotdb-cluster.properties 25 | # sed -i -e 's/^default_replica_num=1$/default_replica_num=3/g' ${snapshotPath}2/conf/iotdb-cluster.properties 26 | # sed -i -e 's/^default_replica_num=1$/default_replica_num=3/g' ${snapshotPath}3/conf/iotdb-cluster.properties 27 | 28 | ##处理 cluster_info_public_port 冲突 29 | sed -i -e 's/#cluster_info_public_port=6567/cluster_info_public_port=6567/g' ${snapshotPath}/conf/iotdb-cluster.properties 30 | sed -i -e 's/#cluster_info_public_port=6567/cluster_info_public_port=6567/g' ${snapshotPath}1/conf/iotdb-cluster.properties 31 | sed -i -e 's/#cluster_info_public_port=6567/cluster_info_public_port=6567/g' ${snapshotPath}2/conf/iotdb-cluster.properties 32 | sed -i -e 's/#cluster_info_public_port=6567/cluster_info_public_port=6567/g' ${snapshotPath}3/conf/iotdb-cluster.properties 33 | sed -i -e 's/cluster_info_public_port=6567/cluster_info_public_port=6568/g' ${snapshotPath}1/conf/iotdb-cluster.properties 34 | sed -i -e 's/cluster_info_public_port=6567/cluster_info_public_port=6569/g' ${snapshotPath}2/conf/iotdb-cluster.properties 35 | sed -i -e 's/cluster_info_public_port=6567/cluster_info_public_port=6570/g' ${snapshotPath}3/conf/iotdb-cluster.properties 36 | 37 | #处理 jmx port 冲突 38 | sed -i -e 's/JMX_PORT="31999"/JMX_PORT="32000"/g' ${snapshotPath}1/conf/iotdb-env.sh 39 | sed -i -e 's/JMX_PORT=31999/JMX_PORT=32000/g' ${snapshotPath}1/conf/iotdb-env.bat 40 | sed -i -e 's/JMX_PORT="31999"/JMX_PORT="32001"/g' ${snapshotPath}2/conf/iotdb-env.sh 41 | sed -i -e 's/JMX_PORT=31999/JMX_PORT=32001/g' ${snapshotPath}2/conf/iotdb-env.bat 42 | sed -i -e 's/JMX_PORT="31999"/JMX_PORT="32002"/g' ${snapshotPath}3/conf/iotdb-env.sh 43 | sed -i -e 's/JMX_PORT=31999/JMX_PORT=32002/g' ${snapshotPath}3/conf/iotdb-env.bat 44 | 45 | #处理 cluster port 冲突 46 | sed -i -e 's/internal_meta_port=9003/internal_meta_port=9005/g' ${snapshotPath}1/conf/iotdb-cluster.properties 47 | sed -i -e 's/internal_data_port=40010/internal_data_port=40012/g' ${snapshotPath}1/conf/iotdb-cluster.properties 48 | 49 | sed -i -e 's/internal_meta_port=9003/internal_meta_port=9007/g' ${snapshotPath}2/conf/iotdb-cluster.properties 50 | sed -i -e 's/internal_data_port=40010/internal_data_port=40014/g' ${snapshotPath}2/conf/iotdb-cluster.properties 51 | 52 | sed -i -e 's/internal_meta_port=9003/internal_meta_port=9009/g' ${snapshotPath}3/conf/iotdb-cluster.properties 53 | sed -i -e 's/internal_data_port=40010/internal_data_port=40016/g' ${snapshotPath}3/conf/iotdb-cluster.properties 54 | 55 | #处理 standalone port 冲突 56 | sed -i -e 's/rpc_port=6667/rpc_port=6669/g' ${snapshotPath}1/conf/iotdb-engine.properties 57 | sed -i -e 's/rpc_port=6667/rpc_port=6671/g' ${snapshotPath}2/conf/iotdb-engine.properties 58 | sed -i -e 's/rpc_port=6667/rpc_port=6673/g' ${snapshotPath}3/conf/iotdb-engine.properties -------------------------------------------------------------------------------- /local/config.sh: -------------------------------------------------------------------------------- 1 | snapshotPath="/Users/txy/Study/iotdb/cluster/target/iotdb-cluster-0.13.0-SNAPSHOT" 2 | 3 | -------------------------------------------------------------------------------- /local/delete.sh: -------------------------------------------------------------------------------- 1 | source ./config.sh 2 | 3 | #删除所有数据 4 | rm -rf $snapshotPath/data $snapshotPath/logs 5 | rm -rf ${snapshotPath}1/data ${snapshotPath}1/logs 6 | rm -rf ${snapshotPath}2/data ${snapshotPath}2/logs 7 | rm -rf ${snapshotPath}3/data ${snapshotPath}3/logs -------------------------------------------------------------------------------- /remote/config.sh: -------------------------------------------------------------------------------- 1 | #测试集群 2 | server=(172.20.70.66 172.20.70.67 172.20.70.68) 3 | #分布式集群的 SEED_NODES 参数 4 | seeds="172.20.70.66:9003,172.20.70.67:9003,172.20.70.68:9003" 5 | #服务器用户 6 | user="cluster" 7 | #服务器测试路径 8 | serverDir="~/txy" 9 | #打包的文件名 10 | snapshotName="iotdb-cluster-0.13.0-SNAPSHOT" 11 | #本地 cluster 模块 maven 打包路径 12 | snapshotPath="/Users/txy/Study/iotdb/cluster/target/${snapshotName}" 13 | #测试集群的执行路径 14 | serverPath="${serverDir}/${snapshotName}" 15 | #从测试集群拉取得到的执行日志本地路径 16 | localLogDir="result" 17 | #更改 iotdb-cluster.properties 中的属性,用|隔开,格式为 key=value,即 key 为参数名称,value 为值的方式替代对应文件中的参数 18 | clusterConfig="seed_nodes=${seeds}|default_replica_num=1" 19 | #更改 iotdb-engine.properties 中的属性,用|隔开,格式为 key=value,即 key 为参数名称,value 为值的方式替代对应文件中的参数 20 | engineConfig="" 21 | #是否后台启动集群 22 | execute=true 23 | -------------------------------------------------------------------------------- /remote/deploy.sh: -------------------------------------------------------------------------------- 1 | source ./config.sh 2 | 3 | if [ "$1" != "np" ]; then 4 | cp -rf $snapshotPath . 5 | for ip in ${server[*]} 6 | do 7 | python3 update.py $snapshotName/conf/iotdb-cluster.properties "internal_ip=${ip}|${clusterConfig}" 8 | python3 update.py $snapshotName/conf/iotdb-engine.properties "rpc_address=${ip}|${engineConfig}" 9 | tar -cvf $snapshotName.tar $snapshotName 10 | ssh $user@$ip "rm -rf ${serverDir};mkdir ${serverDir}" 11 | scp -r $snapshotName.tar $user@$ip:$serverDir 12 | ssh $user@$ip "cd ${serverDir};tar -xvf ${snapshotName}.tar;rm ${snapshotName}.tar;" 13 | rm $snapshotName.tar 14 | done 15 | rm -rf $snapshotName 16 | fi 17 | 18 | if $execute; then 19 | for ip in ${server[*]} 20 | do 21 | ssh $user@$ip "cd ${serverDir}/${snapshotName};rm -rf logs;rm -rf data;mkdir logs;nohup bash ./sbin/start-node.sh printgc >logs/nohup.out 2>&1 &" 22 | done 23 | fi -------------------------------------------------------------------------------- /remote/kill.sh: -------------------------------------------------------------------------------- 1 | source ./config.sh 2 | 3 | for ip in ${server[*]} 4 | do 5 | ssh $user@$ip "cd ${serverPath};bash sbin/stop-node.sh" 6 | done -------------------------------------------------------------------------------- /remote/pull.sh: -------------------------------------------------------------------------------- 1 | source ./config.sh 2 | 3 | rm -rf result 4 | mkdir result 5 | for ip in ${server[*]} 6 | do 7 | rm -rf $localLogDir/$ip 8 | mkdir $localLogDir/$ip 9 | ssh $user@$ip "cd ${serverPath};tar -cvf logs.tar logs" 10 | scp -r $user@$ip:$serverPath/logs.tar $localLogDir/$ip/ 11 | tar -xvf $localLogDir/$ip/logs.tar -C $localLogDir/$ip/ 12 | rm $localLogDir/$ip/logs.tar 13 | done -------------------------------------------------------------------------------- /remote/update.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: UTF-8 -*- 3 | 4 | import re 5 | import os 6 | import tempfile 7 | import sys 8 | 9 | class Properties: 10 | 11 | def __init__(self, file_name): 12 | self.file_name = file_name 13 | self.properties = {} 14 | try: 15 | fopen = open(self.file_name, 'r') 16 | for line in fopen: 17 | line = line.strip() 18 | if line.find('=') > 0 and not line.startswith('#'): 19 | strs = line.split('=') 20 | self.properties[strs[0].strip()] = strs[1].strip() 21 | except Exception : 22 | raise e 23 | else: 24 | fopen.close() 25 | 26 | def has_key(self, key): 27 | return key in self.properties 28 | 29 | def get(self, key, default_value=''): 30 | if key in self.properties: 31 | return self.properties[key] 32 | return default_value 33 | 34 | def put(self, key, value): 35 | self.properties[key] = value 36 | replace_property(self.file_name, key + '=.*', key + '=' + value, True) 37 | 38 | 39 | def replace_property(file_name, from_regex, to_str, append_on_not_exists=True): 40 | tmpfile = tempfile.TemporaryFile() 41 | 42 | if os.path.exists(file_name): 43 | r_open = open(file_name, 'r') 44 | pattern = re.compile(r'' + from_regex) 45 | found = None 46 | for line in r_open: 47 | if pattern.search(line) and not line.strip().startswith('#'): 48 | found = True 49 | line = re.sub(from_regex, to_str, line) 50 | tmpfile.write(line.encode()) 51 | if not found and append_on_not_exists: 52 | tmpfile.write(('\n' + to_str).encode()) 53 | r_open.close() 54 | tmpfile.seek(0) 55 | 56 | content = tmpfile.read() 57 | 58 | if os.path.exists(file_name): 59 | os.remove(file_name) 60 | 61 | w_open = open(file_name, 'wb') 62 | w_open.write(content) 63 | w_open.close() 64 | 65 | tmpfile.close() 66 | else: 67 | print ("file %s not found" % file_name) 68 | 69 | 70 | if __name__ == "__main__": 71 | props = Properties(sys.argv[1]) 72 | if len(sys.argv) > 2 and len(sys.argv) != 0: 73 | paras = sys.argv[2].split("|") 74 | for para in paras: 75 | kv = para.split("=") 76 | props.put(kv[0], kv[1]) --------------------------------------------------------------------------------