Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
fccbc82c
C
ClickHouse
项目概览
2dot5
/
ClickHouse
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
ClickHouse
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
fccbc82c
编写于
3月 17, 2017
作者:
A
Alexey Zatelepin
提交者:
alexey-milovidov
3月 19, 2017
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
translate comments
上级
faadab30
变更
5
展开全部
隐藏空白更改
内联
并排
Showing
5 changed file
with
183 addition
and
173 deletion
+183
-173
dbms/include/DB/Common/ConfigProcessor.h
dbms/include/DB/Common/ConfigProcessor.h
+25
-20
dbms/src/Common/ConfigProcessor.cpp
dbms/src/Common/ConfigProcessor.cpp
+12
-9
libs/libzkutil/include/zkutil/Types.h
libs/libzkutil/include/zkutil/Types.h
+3
-0
libs/libzkutil/include/zkutil/ZooKeeper.h
libs/libzkutil/include/zkutil/ZooKeeper.h
+121
-125
libs/libzkutil/src/ZooKeeper.cpp
libs/libzkutil/src/ZooKeeper.cpp
+22
-19
未找到文件。
dbms/include/DB/Common/ConfigProcessor.h
浏览文件 @
fccbc82c
...
...
@@ -31,29 +31,37 @@ class ConfigProcessor
public:
using
Substitutions
=
std
::
vector
<
std
::
pair
<
std
::
string
,
std
::
string
>
>
;
///
log_to_console нужно использовать, если система логгирования еще не инициализирована
.
///
Set log_to_console to true if the logging subsystem is not initialized yet
.
ConfigProcessor
(
bool
throw_on_bad_incl
=
false
,
bool
log_to_console
=
false
,
const
Substitutions
&
substitutions
=
Substitutions
());
~
ConfigProcessor
();
/** Выполняет подстановки в конфиге и возвращает XML-документ.
*
* Пусть в качестве path передана "/path/file.xml"
* 1) Объединяем xml-дерево из /path/file.xml со всеми деревьями из файлов /path/{conf,file}.d/ *.{conf,xml}
* Если у элемента есть атрибут replace, заменяем на него подходящий элемент.
* Если у элемента есть атрибут remove, удаляем подходящий элемент.
* Иначе объединяем детей рекурсивно.
* 2) Берем из конфига путь к файлу, из которого будем делать подстановки: <include_from>/path2/metrika.xml</include_from>.
* Если путь не указан, используем /etc/metrika.xml
* 3) Заменяем элементы вида "<foo incl="bar"/>" на "<foo>содержимое элемента yandex.bar из metrika.xml</foo>"
* 4) Заменяет "<layer/>" на "<layer>номер слоя из имени хоста</layer>"
*/
/// Perform config includes and substitutions and return the resulting XML-document.
///
/// Suppose path is "/path/file.xml"
/// 1) Merge XML trees of /path/file.xml with XML trees of all files from /path/{conf,file}.d/*.{conf,xml}
/// * If an element has a "replace" attribute, replace the matching element with it.
/// * If an element has a "remove" attribute, remove the matching element.
/// * Else, recursively merge child elements.
/// 2) Determine the includes file from the config: <include_from>/path2/metrika.xml</include_from>
/// If this path is not configured, use /etc/metrika.xml
/// 3) Replace elements matching the "<foo incl="bar"/>" pattern with
/// "<foo>contents of the yandex/bar element in metrika.xml</foo>"
/// 4) If zk_node_cache is non-NULL, replace elements matching the "<foo from_zk="/bar">" pattern with
/// "<foo>contents of the /bar ZooKeeper node</foo>".
/// If has_zk_includes is non-NULL and there are such elements, set has_zk_includes to true.
/// 5) (Yandex.Metrika-specific) Substitute "<layer/>" with "<layer>layer number from the hostname</layer>".
XMLDocumentPtr
processConfig
(
const
std
::
string
&
path
,
bool
*
has_zk_includes
=
nullptr
,
zkutil
::
ZooKeeperNodeCache
*
zk_node_cache
=
nullptr
);
/// loadConfig* functions apply processConfig and create Poco::Util::XMLConfiguration.
/// The resulting XML document is saved into a file with the name
/// resulting from adding "-preprocessed" suffix to the path file name.
/// E.g., config.xml -> config-preprocessed.xml
struct
LoadedConfig
{
ConfigurationPtr
configuration
;
...
...
@@ -62,16 +70,13 @@ public:
bool
preprocessed_written
;
};
/** Делает processConfig и создает из результата Poco::Util::XMLConfiguration.
* Еще сохраняет результат в файл по пути, полученному из path приписыванием строки "-preprocessed" к имени файла.
*/
/// If allow_zk_includes is true, expects that the configuration xml can contain from_zk nodes.
/// If the xml contains them, set has_zk_includes to true and don't write config-preprocessed.xml,
/// If allow_zk_includes is true, expect that the configuration XML can contain from_zk nodes.
/// If it is the case, set has_zk_includes to true and don't write config-preprocessed.xml,
/// expecting that config would be reloaded with zookeeper later.
LoadedConfig
loadConfig
(
const
std
::
string
&
path
,
bool
allow_zk_includes
=
false
);
/// If fallback_to_preprocessed is true, then if KeeperException is thrown during config
/// processing, load the configuration from the preprocessed file.
LoadedConfig
loadConfigWithZooKeeperIncludes
(
const
std
::
string
&
path
,
zkutil
::
ZooKeeperNodeCache
&
zk_node_cache
,
...
...
dbms/src/Common/ConfigProcessor.cpp
浏览文件 @
fccbc82c
...
...
@@ -20,7 +20,7 @@ static bool endsWith(const std::string & s, const std::string & suffix)
return
s
.
size
()
>=
suffix
.
size
()
&&
s
.
substr
(
s
.
size
()
-
suffix
.
size
())
==
suffix
;
}
///
Извлекает из строки первое попавшееся число, состоящее из хотя бы двух цифр
.
///
Extracts from a string the first encountered number consisting of at least two digits
.
static
std
::
string
numberFromHost
(
const
std
::
string
&
s
)
{
for
(
size_t
i
=
0
;
i
<
s
.
size
();
++
i
)
...
...
@@ -66,13 +66,14 @@ ConfigProcessor::~ConfigProcessor()
}
/// Вектор из имени элемента и отсортированного списка имен и значений атрибутов (кроме атрибутов replace и remove).
/// Взаимно однозначно задает имя элемента и список его атрибутов. Нужен, чтобы сравнивать элементы.
/// Vector containing the name of the element and a sorted list of attribute names and values
/// (except "remove" and "replace" attributes).
/// Serves as a unique identifier of the element contents for comparison.
using
ElementIdentifier
=
std
::
vector
<
std
::
string
>
;
using
NamedNodeMapPtr
=
Poco
::
AutoPtr
<
Poco
::
XML
::
NamedNodeMap
>
;
/// NOTE
Можно избавиться от использования Node.childNodes() и итерации по полученному списку, потому что
///
доступ к i-му элементу этого списка работает за O(i)
.
/// NOTE
getting rid of iterating over the result of Node.childNodes() call is a good idea
///
because accessing the i-th element of this list takes O(i) time
.
using
NodeListPtr
=
Poco
::
AutoPtr
<
Poco
::
XML
::
NodeList
>
;
static
ElementIdentifier
getElementIdentifier
(
Node
*
element
)
...
...
@@ -107,7 +108,8 @@ static Node * getRootNode(Document * document)
for
(
size_t
i
=
0
;
i
<
children
->
length
();
++
i
)
{
Node
*
child
=
children
->
item
(
i
);
/// Кроме корневого элемента на верхнем уровне могут быть комментарии. Пропустим их.
/// Besides the root element there can be comment nodes on the top level.
/// Skip them.
if
(
child
->
nodeType
()
==
Node
::
ELEMENT_NODE
)
return
child
;
}
...
...
@@ -135,7 +137,7 @@ void ConfigProcessor::mergeRecursive(XMLDocumentPtr config, Node * config_root,
for
(
Node
*
node
=
config_root
->
firstChild
();
node
;)
{
Node
*
next_node
=
node
->
nextSibling
();
///
Уберем исходный текст из объединяемой части
.
///
Remove text from the original config node
.
if
(
node
->
nodeType
()
==
Node
::
TEXT_NODE
&&
!
allWhitespace
(
node
->
getNodeValue
()))
{
config_root
->
removeChild
(
node
);
...
...
@@ -241,7 +243,8 @@ void ConfigProcessor::doIncludesRecursive(
if
(
node
->
nodeType
()
!=
Node
::
ELEMENT_NODE
)
return
;
/// Будем заменять <layer> на число из имени хоста, только если во входном файле есть тег <layer>, и он пустой, и у него нет атрибутов
/// Substitute <layer> for the number extracted from the hostname only if there is an
/// empty <layer> tag without attributes in the original file.
if
(
node
->
nodeName
()
==
"layer"
&&
!
node
->
hasAttributes
()
&&
!
node
->
hasChildNodes
()
&&
...
...
@@ -259,7 +262,7 @@ void ConfigProcessor::doIncludesRecursive(
if
(
incl_attribute
&&
from_zk_attribute
)
throw
Poco
::
Exception
(
"both incl and from_zk attributes set for element <"
+
node
->
nodeName
()
+
">"
);
///
Заменять имеющееся значение, а не добавлять к нему
.
///
Replace the original contents, not add to it
.
bool
replace
=
attributes
->
getNamedItem
(
"replace"
);
auto
process_include
=
[
&
](
const
Node
*
include_attr
,
const
std
::
function
<
Node
*
(
const
std
::
string
&
)
>
&
get_node
,
const
char
*
error_msg
)
...
...
libs/libzkutil/include/zkutil/Types.h
浏览文件 @
fccbc82c
...
...
@@ -126,6 +126,9 @@ using EventPtr = std::shared_ptr<Poco::Event>;
class
ZooKeeper
;
/// Callback to call when the watch fires.
/// Because callbacks are called in the single "completion" thread internal to libzookeeper,
/// they must execute as quickly as possible (preferably just set some notification).
/// Parameters:
/// zookeeper - zookeeper session to which the fired watch belongs
/// type - event type, one of the *_EVENT constants from zookeeper.h
/// state - session connection state, one of the *_STATE constants from zookeeper.h
...
...
libs/libzkutil/include/zkutil/ZooKeeper.h
浏览文件 @
fccbc82c
此差异已折叠。
点击以展开。
libs/libzkutil/src/ZooKeeper.cpp
浏览文件 @
fccbc82c
...
...
@@ -45,7 +45,7 @@ void check(int32_t code, const std::string path = "")
struct
WatchContext
{
///
существует все время существования WatchContext
///
ZooKeeper instance exists for the entire WatchContext lifetime.
ZooKeeper
&
zk
;
WatchCallback
callback
;
CurrentMetrics
::
Increment
metric_increment
{
CurrentMetrics
::
ZooKeeperWatch
};
...
...
@@ -64,7 +64,8 @@ void ZooKeeper::processCallback(zhandle_t * zh, int type, int state, const char
WatchContext
*
context
=
static_cast
<
WatchContext
*>
(
watcher_ctx
);
context
->
process
(
type
,
state
,
path
);
/// Гарантируется, что не-ZOO_SESSION_EVENT событие придет ровно один раз (https://issues.apache.org/jira/browse/ZOOKEEPER-890).
/// It is guaranteed that non-ZOO_SESSION_EVENT notification will be delivered only once
/// (https://issues.apache.org/jira/browse/ZOOKEEPER-890)
if
(
type
!=
ZOO_SESSION_EVENT
)
destroyContext
(
context
);
}
...
...
@@ -114,7 +115,7 @@ struct ZooKeeperArgs
else
throw
KeeperException
(
std
::
string
(
"Unknown key "
)
+
key
+
" in config file"
);
}
///
перемешиваем порядок хостов, чтобы сделать нагрузку на zookeeper более равномерной
///
Shuffle the hosts to distribute the load among ZooKeeper nodes.
std
::
random_shuffle
(
hosts_strings
.
begin
(),
hosts_strings
.
end
());
for
(
auto
&
host
:
hosts_strings
)
...
...
@@ -234,7 +235,7 @@ int32_t ZooKeeper::tryGetChildren(const std::string & path, Strings & res,
int32_t
ZooKeeper
::
createImpl
(
const
std
::
string
&
path
,
const
std
::
string
&
data
,
int32_t
mode
,
std
::
string
&
path_created
)
{
int
code
;
///
имя ноды может быть больше переданного пути, если создается sequential нода
.
///
The name of the created node can be longer than path if the sequential node is created
.
size_t
name_buffer_size
=
path
.
size
()
+
SEQUENTIAL_SUFFIX_SIZE
;
char
*
name_buffer
=
new
char
[
name_buffer_size
];
...
...
@@ -363,8 +364,8 @@ int32_t ZooKeeper::tryRemoveEphemeralNodeWithRetries(const std::string & path, i
}
catch
(
const
KeeperException
&
)
{
//
Установим флажок, который говорит о том, что сессию лучше воспринимать так же как истёкшую,
///
чтобы кто-нибудь её пересоздал, и, в случае эфемерной ноды, нода всё-таки была удалена
.
//
/ Set the flag indicating that the session is better treated as expired so that someone
///
recreates it and the ephemeral nodes are indeed deleted
.
is_dirty
=
true
;
throw
;
...
...
@@ -437,7 +438,7 @@ int32_t ZooKeeper::getImpl(const std::string & path, std::string & res, Stat * s
if
(
stat_
)
*
stat_
=
stat
;
if
(
buffer_len
<
0
)
///
Такое бывает, если в ноде в ZK лежит NULL. Не будем отличать его от пустой строки
.
if
(
buffer_len
<
0
)
///
This can happen if the node contains NULL. Do not distinguish it from the empty string
.
res
.
clear
();
else
res
.
assign
(
buffer
,
buffer_len
);
...
...
@@ -537,17 +538,19 @@ int32_t ZooKeeper::multiImpl(const Ops & ops_, OpResultsPtr * out_results_)
if
(
ops_
.
empty
())
return
ZOK
;
/// Workaround ошибки в сишном клиенте ZooKeeper. Если сессия истекла, zoo_multi иногда падает с segfault.
/// Наверно, здесь есть race condition, и возможен segfault, если сессия истечет между этой проверкой и zoo_multi.
/// TODO: Посмотреть, не исправлено ли это в последней версии клиента, и исправить.
/// Workaround of the libzookeeper bug. If the session is expired, zoo_multi sometimes
/// segfaults.
/// Possibly, there is a race condition and a segfault is still possible if the session
/// expires between this check and zoo_multi call.
/// TODO: check if the bug is fixed in the latest version of libzookeeper.
if
(
expired
())
return
ZINVALIDSTATE
;
size_t
count
=
ops_
.
size
();
OpResultsPtr
out_results
(
new
OpResults
(
count
));
///
копируем структуру, содержащую указатели, дефолтным конструктором копирования
///
это безопасно, т.к. у нее нет деструктора
///
Copy the struct containing pointers with default copy-constructor.
///
It is safe because it hasn't got a destructor.
std
::
vector
<
zoo_op_t
>
ops
;
for
(
const
auto
&
op
:
ops_
)
ops
.
push_back
(
*
(
op
->
data
));
...
...
@@ -631,9 +634,9 @@ void ZooKeeper::tryRemoveChildrenRecursive(const std::string & path)
ops
.
emplace_back
(
std
::
make_unique
<
Op
::
Remove
>
(
batch
.
back
(),
-
1
));
}
/
** Сначала пытаемся удалить детей более быстрым способом - сразу пачкой. Если не получилось
,
* значит кто-то кроме нас удаляет этих детей, и придется удалять их по одному.
*/
/
// Try to remove the children with a faster method - in bulk. If this fails
,
/// this means someone is concurrently removing these children and we will have
/// to remove them one by one.
if
(
tryMulti
(
ops
)
!=
ZOK
)
{
for
(
const
std
::
string
&
child
:
batch
)
...
...
@@ -664,7 +667,7 @@ void ZooKeeper::waitForDisappear(const std::string & path)
zkutil
::
EventPtr
event
=
std
::
make_shared
<
Poco
::
Event
>
();
std
::
string
unused
;
///
get вместо exists, чтобы не утек watch, если ноды уже нет
.
///
Use get instead of exists to prevent watch leak if the node has already disappeared
.
if
(
!
tryGet
(
path
,
unused
,
nullptr
,
event
))
break
;
...
...
@@ -684,7 +687,7 @@ ZooKeeper::~ZooKeeper()
LOG_INFO
(
&
Logger
::
get
(
"~ZooKeeper"
),
"Removing "
<<
watch_context_store
.
size
()
<<
" watches"
);
///
удаляем WatchContext которые уже никогда не будут обработаны
///
Destroy WatchContexts that will never be used.
for
(
WatchContext
*
context
:
watch_context_store
)
delete
context
;
...
...
@@ -739,7 +742,7 @@ ZooKeeper::GetFuture ZooKeeper::asyncGet(const std::string & path)
throw
KeeperException
(
rc
,
path
);
std
::
string
value_str
;
if
(
value_len
>
0
)
///
Может быть не так, если в ZK лежит NULL. Мы не отличаем его от пустой строки
.
if
(
value_len
>
0
)
///
May be otherwise of the node contains NULL. We don't distinguish it from the empty string
.
value_str
=
{
value
,
size_t
(
value_len
)
};
return
ValueAndStat
{
value_str
,
stat
?
*
stat
:
Stat
()
};
...
...
@@ -772,7 +775,7 @@ ZooKeeper::TryGetFuture ZooKeeper::asyncTryGet(const std::string & path)
throw
KeeperException
(
rc
,
path
);
std
::
string
value_str
;
if
(
value_len
>
0
)
///
Может быть не так, если в ZK лежит NULL. Мы не отличаем его от пустой строки
.
if
(
value_len
>
0
)
///
May be otherwise of the node contains NULL. We don't distinguish it from the empty string
.
value_str
=
{
value
,
size_t
(
value_len
)
};
return
ValueAndStatAndExists
{
value_str
,
stat
?
*
stat
:
Stat
(),
rc
!=
ZNONODE
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录