generated from pinterest/.github
-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #281 from pinterest/orion-clickhouse-sense-cluster…
…s-nodes Add Orion sensor for ClickHouse clusters/nodes
- Loading branch information
Showing
8 changed files
with
264 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 125 additions & 0 deletions
125
...n/java/com/pinterest/orion/core/automation/sensor/clickhouse/ClickHouseClusterSensor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package com.pinterest.orion.core.automation.sensor.clickhouse; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Paths; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import java.util.concurrent.ExecutionException; | ||
|
||
import com.clickhouse.client.ClickHouseClient; | ||
import com.clickhouse.client.ClickHouseCredentials; | ||
import com.clickhouse.client.ClickHouseException; | ||
import com.clickhouse.client.ClickHouseNode; | ||
import com.clickhouse.client.ClickHouseProtocol; | ||
import com.clickhouse.client.ClickHouseResponse; | ||
import com.clickhouse.data.ClickHouseFormat; | ||
import com.clickhouse.data.ClickHouseRecord; | ||
|
||
import com.pinterest.orion.common.NodeInfo; | ||
import com.pinterest.orion.core.Node; | ||
import com.pinterest.orion.core.PluginConfigurationException; | ||
import com.pinterest.orion.core.clickhouse.ClickHouseCluster; | ||
import com.pinterest.orion.core.clickhouse.ClickHouseNodeInfo; | ||
|
||
public class ClickHouseClusterSensor extends ClickHouseSensor { | ||
|
||
public static final String CLUSTER_COL = "cluster"; | ||
public static final String SHARD_NUM_COL = "shard_num"; | ||
public static final String SHARD_WEIGHT_COL = "shard_weight"; | ||
public static final String REPLICA_NUM_COL = "replica_num"; | ||
public static final String HOST_NAME_COL = "host_name"; | ||
|
||
public static final String CLUSTERS_QUERY = "SELECT * FROM system.clusters WHERE is_local=1"; | ||
|
||
private Map<String, Object> config; | ||
|
||
@Override | ||
public String getName() { | ||
return "clickhouseclustersensor"; | ||
} | ||
|
||
@Override | ||
public void initialize(Map<String, Object> config) throws PluginConfigurationException { | ||
super.initialize(config); | ||
} | ||
|
||
private void addNodesFromServerSet(ClickHouseCluster cluster, String serversetPath) throws Exception { | ||
List<String> lines = Files.readAllLines(new File(serversetPath).toPath()); | ||
for (String serverStr : lines) { | ||
ClickHouseNodeInfo nodeInfo = new ClickHouseNodeInfo(); | ||
nodeInfo.setNodeId(serverStr); | ||
nodeInfo.setClusterId(cluster.getClusterId()); | ||
|
||
String[] splits = serverStr.split(":"); | ||
String ip = splits[0]; | ||
int port = Integer.parseInt(splits[1]); | ||
nodeInfo.setIp(ip); | ||
nodeInfo.setServicePort(port); | ||
|
||
queryShardReplicaInfoFromNode(cluster, nodeInfo, ip, port); | ||
|
||
Node node = cluster.getNodeMap().get(serverStr); | ||
if (node == null) { | ||
logger.info("Adding new node with info " + nodeInfo); | ||
} else { | ||
logger.info("Updating node; existing info " + node.getCurrentNodeInfo() | ||
+ ", new info " + nodeInfo); | ||
} | ||
cluster.addNodeWithoutAgent(nodeInfo); | ||
} | ||
} | ||
|
||
@Override | ||
public void sense(ClickHouseCluster cluster) throws Exception { | ||
String serversetPath = cluster.getAttribute(cluster.SERVERSET_PATH).getValue(); | ||
addNodesFromServerSet(cluster, serversetPath); | ||
} | ||
|
||
private void queryShardReplicaInfo( | ||
ClickHouseNode server, ClickHouseNodeInfo nodeInfo) throws ClickHouseException { | ||
try (ClickHouseClient client = ClickHouseClient.newInstance(server.getProtocol()); | ||
// each node stores the clusters info in the table system.clusters | ||
// here we query the shard/replica info each node stores for itself | ||
// TODO: build an auditor action to make sure each node stores | ||
// the consistent info about all the other nodes | ||
ClickHouseResponse response = client.read(server) | ||
.format(ClickHouseFormat.RowBinaryWithNamesAndTypes) | ||
.query(CLUSTERS_QUERY).execute().get()) { | ||
for (ClickHouseRecord r : response.records()) { | ||
// note that within each cluster, there can be smaller | ||
// logical clusters, e.g. created using `Replicated` | ||
String cluster = r.getValue(CLUSTER_COL).asString(); | ||
int shard = r.getValue(SHARD_NUM_COL).asInteger(); | ||
int shardWeight = r.getValue(SHARD_WEIGHT_COL).asInteger(); | ||
int replicaNum = r.getValue(REPLICA_NUM_COL).asInteger(); | ||
String hostName = r.getValue(HOST_NAME_COL).asString(); | ||
|
||
nodeInfo.setHostname(hostName); | ||
nodeInfo.addShardReplicaInfo(cluster, shard, shardWeight, replicaNum); | ||
} | ||
} catch (InterruptedException e) { | ||
Thread.currentThread().interrupt(); | ||
throw ClickHouseException.forCancellation(e, server); | ||
} catch (ExecutionException e) { | ||
throw ClickHouseException.of(e, server); | ||
} | ||
} | ||
|
||
private void queryShardReplicaInfoFromNode( | ||
ClickHouseCluster cluster, ClickHouseNodeInfo nodeInfo, String host, int port) | ||
throws ClickHouseException { | ||
String user = cluster.getAttribute(cluster.USER).getValue(); | ||
String password = cluster.getAttribute(cluster.PASSWORD).getValue(); | ||
|
||
ClickHouseNode server = ClickHouseNode.builder() | ||
.host(host) | ||
.port(ClickHouseProtocol.HTTP, port) | ||
.database("system").credentials( | ||
ClickHouseCredentials.fromUserAndPassword(user, password) | ||
).build(); | ||
queryShardReplicaInfo(server, nodeInfo); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...src/main/java/com/pinterest/orion/core/automation/sensor/clickhouse/ClickHouseSensor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.pinterest.orion.core.automation.sensor.clickhouse; | ||
|
||
import com.pinterest.orion.core.Cluster; | ||
import com.pinterest.orion.core.automation.sensor.Sensor; | ||
import com.pinterest.orion.core.clickhouse.ClickHouseCluster; | ||
|
||
public abstract class ClickHouseSensor extends Sensor { | ||
|
||
@Override | ||
public void observe(Cluster cluster) throws Exception { | ||
if (logger == null) { | ||
logger = getLogger(cluster); | ||
} | ||
if(cluster instanceof ClickHouseCluster){ | ||
sense((ClickHouseCluster) cluster); | ||
} | ||
} | ||
|
||
public abstract void sense(ClickHouseCluster cluster) throws Exception; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
orion-server/src/main/java/com/pinterest/orion/core/clickhouse/ClickHouseNodeInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.pinterest.orion.core.clickhouse; | ||
|
||
import com.pinterest.orion.common.NodeInfo; | ||
|
||
import java.io.Serializable; | ||
import java.util.Map; | ||
import java.util.HashMap; | ||
|
||
class ShardReplicaInfo { | ||
public int shardNum; | ||
public int shardWeight; | ||
public int replicaNum; | ||
|
||
ShardReplicaInfo(int shardNum, int shardWeight, int replicaNum) { | ||
this.shardNum = shardNum; | ||
this.shardWeight = shardWeight; | ||
this.replicaNum = replicaNum; | ||
} | ||
|
||
public String toString() { | ||
return "{shardNum: " + shardNum + ", shardWeight: " | ||
+ shardWeight + " replicaNum: " + replicaNum + "}"; | ||
} | ||
} | ||
|
||
public class ClickHouseNodeInfo extends NodeInfo implements Serializable { | ||
Map<String, ShardReplicaInfo> infoByCluster = new HashMap<>(); | ||
|
||
public void addShardReplicaInfo(String cluster, int shardNum, int shardWeight, int replicaNum) { | ||
infoByCluster.put(cluster, new ShardReplicaInfo(shardNum, shardWeight, replicaNum)); | ||
} | ||
|
||
public int getShardNum(String cluster) { | ||
return infoByCluster.get(cluster).shardNum; | ||
} | ||
|
||
public int getShardWeight(String cluster) { | ||
return infoByCluster.get(cluster).shardWeight; | ||
} | ||
|
||
public int getReplicaNum(String cluster) { | ||
return infoByCluster.get(cluster).replicaNum; | ||
} | ||
|
||
@Override | ||
protected String listPropertiesStr() { | ||
return super.listPropertiesStr() + ", infoByCluster=" + infoByCluster.toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
orion-server/src/test/resources/configs/clickhouse-server.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
logging: | ||
level: INFO | ||
appenders: | ||
- type: file | ||
# The file to which current statements will be logged. | ||
currentLogFilename: /var/log/orion/orion.log | ||
# When the log file rotates, the archived log will be renamed to this and gzipped. The | ||
# %d is replaced with the previous day (yyyy-MM-dd). Custom rolling windows can be created | ||
# by passing a SimpleDateFormat-compatible format as an argument: "%d{yyyy-MM-dd-hh}". | ||
archivedLogFilenamePattern: /var/log/orion/orion-%d.log.gz | ||
# The number of archived files to keep. | ||
archivedFileCount: 5 | ||
|
||
server: | ||
requestLog: | ||
appenders: [] | ||
applicationConnectors: | ||
- type: http | ||
port: 8090 | ||
bindHost: 127.0.0.1 | ||
adminConnectors: | ||
- type: http | ||
port: 8444 | ||
bindHost: 0.0.0.0 | ||
|
||
clusterConfigs: | ||
- clusterId: testclickhouse | ||
type: clickhouse | ||
configuration: | ||
serversetPath: /opt/orion-server/discovery.testclickhouse.test | ||
|
||
plugins: | ||
sensorConfigs: | ||
- key: clusterSensor | ||
class: com.pinterest.orion.core.automation.sensor.clickhouse.ClickHouseClusterSensor | ||
interval: 60 | ||
enabled: true |