Husky中文文档-C++ Husky 基础

纲要

一个c++ husky程序的框架如下:

void job() {
   // work ...
}

int main(int argc, char ** argv) {
    Husky::run_job(job, argv[1]);
    return 0;
}

我们在job函数中实现程序逻辑。首先,我们需要在程序的开头创建一个husky worker.

auto & worker = Husky::Context::get_worker<Husky::BaseWorker>();

相应地,我们需要在程序的末尾移除该worker。

Husky::Context::free_worker<Husky::BaseWorker>();

一个简单的程序

在我们设置文件中,每一个线程都将创建它们自己的worker。紧接着,我们需要通过该worker创建出husky对象。对象是husky最小单位的数据抽象。例如,我们可以首先定义如下的User类并接着创建对象。

class User : public Husky::BaseObject {
public:
    typedef int KeyT;   // Key type of this class of object
    const KeyT & id() const { return user_id; }
    KeyT user_id; // the identity of User object
};

如上是最简单的Husky对象。因为它仅仅定义了它的key和对应的key的类型。我们可以从文件中读入数据,创建并初始化这些对象。我们假设输入是文本文件,每一行有一个数字,表示不同用户的id。

auto & user_list = worker.create_list<User>("user-list");   // 创建一个可存储user对象的husky列表
Husky::HDFSLineInputFormat infmt;
infmt.set_input("/path/to/file");
worker.load(infmt, [&](boost:string_ref line){
    uid = std::stoi(line);
    User user;
    user.user_id = uid;
    worker.add_object(user_list, user);  // 往该object list添加对象
});

上述代码创建了一个对象列表,然后按行读入输入文件,并依据该行的数据来创建并初始化对应的对象。每一个worker都会读取整个输入文件中的一部分,使得传输和并行处理的效率最大化。最后,每个worker都创建并保存一些user对象。

然而,他们并不知道在其他worker上面创建了哪些user对象。也既是说,在非本地的worker上的对象是不可见的。

可以通过以下方法便可使对象全局可见。

worker.globalize_list(user_list);

创建参数

有时候,你可能需要从配置文件读入一些参数。例如,我们需要从配置文件取得以上程序中的输入,那么我们应该在配置文件新添加一行并增加一个key:value对:

input:/data/to/path

请注意这里的key和value是以:号(需要使用英文输入法)分隔的。这样我们便可以通过Husky::Context::get_params(key)这个API来取得这一参数:

infmt.set_input(Husky::Context::get_params("input"));  // 这里的key是 `input`

需要注意的是,我们从Husky::Context::get_params取得的永远是 std::string 类型,在某些情况下,您可能需要将其转变成整数或浮点数。

基本消息传递

以下例子展现其余用户向user 0发送消息(内容为数字1)。

worker.list_execute(user_list, [&](User & user) {
    if(user.id() != 0)
        Husky::send_message(1, 0, user_list);  // (Msg, Key, Obj_List)
});

当你有许多user的时候,消息传递可能会占用大量网络并限制数据处理速度。为此,Husky提供了Combiner来整合来自同一个worker上的消息。可以如下操作:

worker.list_execute(user_list, [&](User & user) {
    if(user.id() != 0)
        Husky::send_message<Husky::SumCombine<int> >(1, 0, user_list);  // (Msg, Key, Obj_List)
});

在接下来的list_execute, 每一个对象可以获取其他对象发给它的消息。

worker.list_execute(user_list, [&](User & user){
    auto & msgs = Husky::get_messages<int>(user); // 消息类型为int
    int cnt = 0;
    for (auto m : msgs)
        cnt += m;
    if(cnt != 0)
        Husky::log_msg(std::to_string(user.id())+" recv "+std::to_string(cnt)+" msgs.");
});

更多例子

我们在example/目录下提供丰富的例子来辅助快速开发一个基于Husky的分布式程序。

例如,pi.cpp这一文件提供许多基本c++ API的使用方法。wc-mr.cpp展示了如何使用inputformattopkpi-agg.cpp使用了aggregator。

我们将会在后续一些章节中介绍combiner,aggregator和broadcast等API。

你可能感兴趣的:(Husky中文文档-C++ Husky 基础)