2016-03-23 21:36:47 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <threadpool.hpp>
|
|
|
|
|
#include <DB/Databases/IDatabase.h>
|
2016-03-26 03:03:50 +00:00
|
|
|
|
#include <DB/Common/UInt128.h>
|
2016-03-23 21:36:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/** Позволяет создавать "облачные таблицы".
|
|
|
|
|
* Список таких таблиц хранится в ZooKeeper.
|
|
|
|
|
* Все серверы, ссылающиеся на один путь в ZooKeeper, видят один и тот же список таблиц.
|
|
|
|
|
* CREATE, DROP, RENAME атомарны.
|
|
|
|
|
*
|
|
|
|
|
* Для БД задаётся уровень репликации N.
|
|
|
|
|
* При записи в "облачную" таблицу, некоторым образом выбирается N живых серверов в разных датацентрах,
|
|
|
|
|
* на каждом из них создаётся локальная таблица, и в них производится запись.
|
|
|
|
|
*
|
|
|
|
|
* Движок имеет параметры: Cloud(zookeeper_path, replication_factor, datacenter_name)
|
|
|
|
|
* Пример: Cloud('/clickhouse/clouds/production/', 3, 'FIN')
|
|
|
|
|
*
|
|
|
|
|
* Структура в ZooKeeper:
|
|
|
|
|
*
|
|
|
|
|
* cloud_path - путь к "облаку"; может существовать несколько разных независимых облаков
|
|
|
|
|
/table_definitions - множество уникальных определений таблиц, чтобы не писать их много раз для большого количества таблиц
|
|
|
|
|
/hash128 -> sql - отображение: хэш от определения таблицы (идентификатор) -> само определение таблицы в виде CREATE запроса
|
|
|
|
|
/tables - список таблиц
|
|
|
|
|
/database_name - имя базы данных
|
|
|
|
|
/name_hash_mod -> compressed_table_list
|
|
|
|
|
- список таблиц сделан двухуровневым, чтобы уменьшить количество узлов в ZooKeeper при наличии большого количества таблиц
|
|
|
|
|
- узлы создаются для каждого остатка от деления хэша от имени таблицы, например, на 4096
|
2016-03-26 03:03:50 +00:00
|
|
|
|
- и в каждом узле хранится список таблиц (имя таблицы, имя локальной таблицы, хэш от структуры, список хостов) в сжатом виде
|
|
|
|
|
/local_tables - список локальных таблиц, чтобы по имени локальной таблицы можно было определить её структуру
|
|
|
|
|
/database_name
|
|
|
|
|
/name_hash_mod -> compressed_table_list
|
|
|
|
|
- список пар (хэш от имени таблицы, хэш от структуры) в сжатом виде
|
2016-04-05 15:05:45 +00:00
|
|
|
|
/locality_keys - сериализованный список ключей локальности в порядке их появления
|
2016-03-23 21:36:47 +00:00
|
|
|
|
- ключ локальности - произвольная строка
|
2016-04-05 15:05:45 +00:00
|
|
|
|
- движок БД определяет серверы для расположения данных таким образом,
|
|
|
|
|
чтобы, при одинаковом множестве живых серверов,
|
2016-03-23 21:36:47 +00:00
|
|
|
|
одному ключу локальности соответствовала одна группа из N серверов для расположения данных.
|
|
|
|
|
/nodes - список серверов, на которых зарегистрированы облачные БД с таким путём в ZK
|
|
|
|
|
/hostname - имя хоста
|
2016-03-26 03:03:50 +00:00
|
|
|
|
TODO /alive - эфемерная нода для предварительной проверки живости
|
2016-03-23 21:36:47 +00:00
|
|
|
|
/datacenter - имя датацентра
|
2016-03-26 03:03:50 +00:00
|
|
|
|
TODO /disk_space
|
2016-03-23 21:36:47 +00:00
|
|
|
|
|
|
|
|
|
* К одному облаку может относиться несколько БД, названных по-разному. Например, БД hits и visits могут относиться к одному облаку.
|
|
|
|
|
*/
|
|
|
|
|
class DatabaseCloud : public IDatabase
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
const String name;
|
|
|
|
|
const String data_path;
|
|
|
|
|
String zookeeper_path;
|
|
|
|
|
const size_t replication_factor;
|
|
|
|
|
const String hostname;
|
|
|
|
|
const String datacenter_name;
|
|
|
|
|
|
|
|
|
|
Logger * log;
|
|
|
|
|
|
|
|
|
|
Context & context;
|
|
|
|
|
|
2016-03-26 03:03:50 +00:00
|
|
|
|
/** Локальные таблицы - это таблицы, находящиеся непосредственно на локальном сервере.
|
|
|
|
|
* Они хранят данные облачных таблиц: облачная таблица представлена несколькими локальными таблицами на разных серверах.
|
|
|
|
|
* Эти таблицы не видны пользователю при перечислении таблиц, хотя доступны при обращении по имени.
|
|
|
|
|
* Имя локальных таблиц имеет специальную форму, например, начинаться на _local, чтобы они не путались с облачными таблицами.
|
|
|
|
|
* Локальные таблицы загружаются лениво, при первом обращении.
|
|
|
|
|
*/
|
|
|
|
|
Tables local_tables_cache;
|
|
|
|
|
mutable std::mutex local_tables_mutex;
|
|
|
|
|
|
2016-03-26 04:13:15 +00:00
|
|
|
|
friend class DatabaseCloudIterator;
|
|
|
|
|
|
2016-03-23 21:36:47 +00:00
|
|
|
|
public:
|
|
|
|
|
DatabaseCloud(
|
|
|
|
|
bool attach,
|
|
|
|
|
const String & name_,
|
|
|
|
|
const String & zookeeper_path_,
|
|
|
|
|
size_t replication_factor_,
|
|
|
|
|
const String & datacenter_name_,
|
|
|
|
|
Context & context_,
|
|
|
|
|
boost::threadpool::pool * thread_pool);
|
|
|
|
|
|
|
|
|
|
String getEngineName() const override { return "Cloud"; }
|
|
|
|
|
|
|
|
|
|
bool isTableExist(const String & table_name) const override;
|
|
|
|
|
StoragePtr tryGetTable(const String & table_name) override;
|
|
|
|
|
|
|
|
|
|
DatabaseIteratorPtr getIterator() override;
|
|
|
|
|
|
|
|
|
|
bool empty() const override;
|
|
|
|
|
|
|
|
|
|
void createTable(const String & table_name, const StoragePtr & table, const ASTPtr & query, const String & engine) override;
|
2016-03-26 04:44:49 +00:00
|
|
|
|
void removeTable(const String & table_name) override;
|
2016-03-23 21:36:47 +00:00
|
|
|
|
|
|
|
|
|
void attachTable(const String & table_name, const StoragePtr & table) override;
|
|
|
|
|
StoragePtr detachTable(const String & table_name) override;
|
|
|
|
|
|
|
|
|
|
void renameTable(const Context & context, const String & table_name, IDatabase & to_database, const String & to_table_name) override;
|
|
|
|
|
|
|
|
|
|
ASTPtr getCreateQuery(const String & table_name) const override;
|
|
|
|
|
|
|
|
|
|
void shutdown() override;
|
2016-03-28 11:19:14 +00:00
|
|
|
|
void drop() override;
|
2016-03-23 21:36:47 +00:00
|
|
|
|
|
2016-03-26 03:03:50 +00:00
|
|
|
|
using Hash = UInt128;
|
|
|
|
|
|
2016-03-23 21:36:47 +00:00
|
|
|
|
private:
|
|
|
|
|
void createZookeeperNodes();
|
2016-04-05 15:05:45 +00:00
|
|
|
|
|
|
|
|
|
/// Получить имя узла, в котором будет храниться часть списка таблиц. (Список таблиц является двухуровневым.)
|
2016-03-26 03:03:50 +00:00
|
|
|
|
String getNameOfNodeWithTables(const String & table_name) const;
|
2016-04-05 15:05:45 +00:00
|
|
|
|
|
|
|
|
|
/// Хэшировать имя таблицы вместе с именем БД.
|
2016-03-26 03:03:50 +00:00
|
|
|
|
Hash getTableHash(const String & table_name) const;
|
2016-04-04 21:41:16 +00:00
|
|
|
|
|
2016-04-05 15:05:45 +00:00
|
|
|
|
/// Определения таблиц хранятся косвенным образом и адресуются своим хэшом. Вычислить хэш.
|
2016-04-04 21:41:16 +00:00
|
|
|
|
Hash getHashForTableDefinition(const String & definition) const;
|
2016-04-05 15:05:45 +00:00
|
|
|
|
|
|
|
|
|
/// Пойти в ZooKeeper и по хэшу получить определение таблицы.
|
2016-03-26 03:03:50 +00:00
|
|
|
|
String getTableDefinitionFromHash(Hash hash) const;
|
2016-04-05 15:05:45 +00:00
|
|
|
|
|
|
|
|
|
/// Определить серверы, на которых будут храниться данные таблицы.
|
|
|
|
|
std::vector<String> selectHostsForTable(const String & locality_key) const;
|
2016-03-23 21:36:47 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|