2021-11-11 09:03:53 +00:00
|
|
|
#pragma once
|
|
|
|
|
2021-11-15 14:52:52 +00:00
|
|
|
#include <Common/ConcurrentBoundedQueue.h>
|
|
|
|
#include <Common/ThreadPool.h>
|
2021-11-11 09:03:53 +00:00
|
|
|
#include <Common/ZooKeeper/Common.h>
|
2021-11-29 12:35:28 +00:00
|
|
|
#include <base/getFQDNOrHostName.h>
|
2021-11-16 12:01:30 +00:00
|
|
|
#include <Interpreters/Cluster.h>
|
2021-11-11 09:03:53 +00:00
|
|
|
|
2021-11-15 14:52:52 +00:00
|
|
|
#include <Poco/Logger.h>
|
|
|
|
|
|
|
|
#include <base/defines.h>
|
|
|
|
|
|
|
|
#include <unordered_map>
|
2021-11-11 09:03:53 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2021-11-16 12:01:30 +00:00
|
|
|
/*
|
|
|
|
* Discover cluster nodes.
|
|
|
|
*
|
|
|
|
* Each node adds ephemernal node into specified path in zookeeper (each cluster have own path).
|
2021-11-16 13:39:54 +00:00
|
|
|
* Also node subscribed for updates for these paths, and at each child node chanhe cluster updated.
|
2021-11-16 12:01:30 +00:00
|
|
|
* When node goes down ephemernal node are destroyed, cluster configuration is updated on other node and gone node is removed from cluster.
|
|
|
|
*/
|
2021-11-11 09:03:53 +00:00
|
|
|
class ClusterDiscovery
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
ClusterDiscovery(
|
|
|
|
const Poco::Util::AbstractConfiguration & config,
|
2021-11-18 08:57:26 +00:00
|
|
|
ContextPtr context_,
|
2021-11-18 09:45:57 +00:00
|
|
|
const String & config_prefix = "remote_servers");
|
2021-11-11 09:03:53 +00:00
|
|
|
|
|
|
|
void start();
|
|
|
|
|
2021-11-15 14:52:52 +00:00
|
|
|
~ClusterDiscovery();
|
2021-11-11 09:03:53 +00:00
|
|
|
|
|
|
|
private:
|
2021-11-16 13:39:54 +00:00
|
|
|
struct NodeInfo
|
|
|
|
{
|
2021-12-07 09:07:30 +00:00
|
|
|
/// versioning for format of data stored in zk
|
|
|
|
static constexpr size_t data_ver = 1;
|
|
|
|
|
2021-11-16 13:39:54 +00:00
|
|
|
/// host:port
|
|
|
|
String address;
|
2021-11-19 07:21:40 +00:00
|
|
|
/// is secure tcp port user
|
|
|
|
bool secure = false;
|
2021-11-29 12:35:28 +00:00
|
|
|
/// shard number
|
|
|
|
size_t shard_id = 0;
|
2021-11-16 13:39:54 +00:00
|
|
|
|
2021-11-17 14:16:49 +00:00
|
|
|
NodeInfo() = default;
|
2021-11-29 12:35:28 +00:00
|
|
|
explicit NodeInfo(const String & address_, bool secure_, size_t shard_id_)
|
|
|
|
: address(address_)
|
|
|
|
, secure(secure_)
|
|
|
|
, shard_id(shard_id_)
|
|
|
|
{}
|
2021-11-17 14:16:49 +00:00
|
|
|
|
|
|
|
static bool parse(const String & data, NodeInfo & result);
|
|
|
|
String serialize() const;
|
2021-11-16 13:39:54 +00:00
|
|
|
};
|
|
|
|
|
2021-11-16 12:01:30 +00:00
|
|
|
// node uuid -> address ("host:port")
|
2021-11-16 13:39:54 +00:00
|
|
|
using NodesInfo = std::unordered_map<String, NodeInfo>;
|
2021-11-16 12:01:30 +00:00
|
|
|
|
|
|
|
struct ClusterInfo
|
|
|
|
{
|
|
|
|
const String name;
|
|
|
|
const String zk_root;
|
|
|
|
NodesInfo nodes_info;
|
|
|
|
|
2021-12-07 12:51:27 +00:00
|
|
|
/// Track last update time
|
|
|
|
Stopwatch watch;
|
|
|
|
|
2021-11-29 12:35:28 +00:00
|
|
|
NodeInfo current_node;
|
|
|
|
|
|
|
|
explicit ClusterInfo(const String & name_, const String & zk_root_, UInt16 port, bool secure, size_t shard_id)
|
|
|
|
: name(name_)
|
|
|
|
, zk_root(zk_root_)
|
|
|
|
, current_node(getFQDNOrHostName() + ":" + toString(port), secure, shard_id)
|
|
|
|
{
|
|
|
|
}
|
2021-11-16 12:01:30 +00:00
|
|
|
};
|
|
|
|
|
2021-12-27 12:41:09 +00:00
|
|
|
void initialUpdate();
|
|
|
|
|
2021-11-16 12:01:30 +00:00
|
|
|
void registerInZk(zkutil::ZooKeeperPtr & zk, ClusterInfo & info);
|
|
|
|
|
2021-11-16 09:02:44 +00:00
|
|
|
Strings getNodeNames(zkutil::ZooKeeperPtr & zk,
|
|
|
|
const String & zk_root,
|
|
|
|
const String & cluster_name,
|
|
|
|
int * version = nullptr,
|
|
|
|
bool set_callback = true);
|
|
|
|
|
2021-11-17 14:16:49 +00:00
|
|
|
NodesInfo getNodes(zkutil::ZooKeeperPtr & zk, const String & zk_root, const Strings & node_uuids);
|
2021-11-15 14:52:52 +00:00
|
|
|
|
2021-11-19 09:42:00 +00:00
|
|
|
ClusterPtr makeCluster(const ClusterInfo & cluster_info);
|
2021-11-16 12:01:30 +00:00
|
|
|
|
2021-11-17 13:47:40 +00:00
|
|
|
bool needUpdate(const Strings & node_uuids, const NodesInfo & nodes);
|
2021-11-16 12:01:30 +00:00
|
|
|
bool updateCluster(ClusterInfo & cluster_info);
|
2021-11-11 09:03:53 +00:00
|
|
|
|
2021-12-20 15:43:11 +00:00
|
|
|
bool runMainThread(std::function<void()> up_to_date_callback);
|
2021-11-15 14:52:52 +00:00
|
|
|
void shutdown();
|
|
|
|
|
2021-11-16 12:01:30 +00:00
|
|
|
/// cluster name -> cluster info (zk root, set of nodes)
|
|
|
|
std::unordered_map<String, ClusterInfo> clusters_info;
|
2021-11-11 09:03:53 +00:00
|
|
|
|
|
|
|
ContextMutablePtr context;
|
|
|
|
|
2021-11-25 13:45:38 +00:00
|
|
|
String current_node_name;
|
2021-11-11 09:03:53 +00:00
|
|
|
|
2021-11-17 11:32:20 +00:00
|
|
|
template <typename T> class ConcurrentFlags;
|
|
|
|
using UpdateFlags = ConcurrentFlags<std::string>;
|
2021-11-16 12:01:30 +00:00
|
|
|
|
2021-11-17 11:32:20 +00:00
|
|
|
/// Cluster names to update.
|
|
|
|
/// The `shared_ptr` is used because it's passed to watch callback.
|
|
|
|
/// It prevents accessing to invalid object after ClusterDiscovery is destroyed.
|
|
|
|
std::shared_ptr<UpdateFlags> clusters_to_update;
|
2021-11-16 12:01:30 +00:00
|
|
|
|
2021-11-15 14:52:52 +00:00
|
|
|
ThreadFromGlobalPool main_thread;
|
|
|
|
|
2021-11-11 09:03:53 +00:00
|
|
|
Poco::Logger * log;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|