[Bro-Dev] [Bro-Commits] [git/bro] topic/actor-system: First-pass broker-enabled Cluster scripting API + misc. (07ad06b)
Jan Grashöfer
jan.grashoefer at gmail.com
Fri Nov 3 03:51:55 PDT 2017
On 02/11/17 23:58, Azoff, Justin S wrote:
> For an example of a purely broadcast use case, see
>
> scripts/base/frameworks/intel/cluster.bro
>
> You can see the crazy amount of complexity around the Intel::cluster_new_item event.
That's right! Took me some time to figure out how data should be
distributed. So, I am following this thread trying to keep up with the
development. Right now I don't have new ideas to contribute but as the
intel framework was mentioned multiple times as an example, I thought I
might sketch its communication behavior, so that we have a more complete
view of that use case.
Let's assume in the beginning there is only the manager. The manager
reads in the intel file and creates his "in-memory database", a quite
complex table (DataStore), as well as a data structure that contains
only the indicators for matching on the workers (MinDataStore).
Now, when a worker connects, he receives the current MinDataStore, sent
using send_id. (Side note: I am planning to replace the sets used in the
MinDataStore by Cuckoo Filters. Not sure how serialization etc. will
work out using broker but if I remember correctly there is a temporary
solution for now.) If the worker detects a match, he triggers
match_no_items on the manager, who generates the hit by combining the
seen data of the worker and the meta data of the DataStore.
At this point, if the manager functionality is distributed across
multiple data nodes, we have to make sure, that every data node has the
right part of the DataStore to deal with the incoming hit. One could
keep the complete DataStore on every data node but I think that would
lead to another scheme in which a subset of workers send all their
requests to a specific data node, i.e. each data node serves a part of
the cluster.
Back to the current implementation. So far not that complex but there
are two more cases to deal with: Inserting new intel items and removing
items. A new item can be inserted on the manager or on a worker. As a
new item might be just new meta data for an already existing indicator
(no update of the MinDataStore needed), the manager is the only one who
can handle the insert. So if inserted on a worker, the worker triggers a
cluster_new_item event on the manager, who proceeds like he inserted the
item. Finally, the manager only triggers cluster_new_item on the workers
if the inserted item was a new indicator that has to be added to the
worker's MinDataStores. Some of the complexity here is due to the fact
that the same event, cluster_new_item, is used for communication in both
directions (worker2manager and manager2worker). The removal of items
works more or less the same with the only difference that for each
direction there is a specific event (remove_item and purge_item).
Long story short: I think the built in distribution across multiple data
nodes you discussed is a great idea. The only thing to keep in mind
would be a suitable way of "initializing" the data nodes with the
corresponding subset of data they need to handle. I guess in case of the
intel framework the manager will still handle reading the intel files
and might make use of the same mechanisms the workers use to distribute
the ingested data to the data nodes. The only thing I am not sure about
is how we can/should handle dynamic adding and removing of the data nodes.
And just to avoid misunderstandings: We won't be able to get rid of the
@if (Cluster::local_node_type() != Cluster::MANAGER/DATANODE)
statements completely as different node types have different
functionality. It's just about the communication API, right?
I hope this helps when thinking about the API design :)
Jan
More information about the bro-dev
mailing list