-
Notifications
You must be signed in to change notification settings - Fork 463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simple rr-network load balancer #1706
Conversation
This user does not have permission to start the build. Can one of the admins verify this patch and start the build? (admin please type: ok to test) |
@kira-syslogng ok to test. |
The idea is clever. |
Build SUCCESS, the tests were executed on test branch: master and test suite: functions |
In many LB scenarios you will end up loosing sequence, but of course you use some slng assigned sequence number to reproduce it. Anyhow this is a simple solution that is useful for scenarios where strict sequencing is not important, but you have lot of logs and need to just distribute it. You can of course use "sticky host" load-balancing, but that might be a limitation where one host produces too many logs. Also in case of larger deployments with multiple nodes producing logs the strict sequence is probably not that important. |
Build SUCCESS, the tests were executed on test branch: master and test suite: functions |
Random set of thoughts:
|
scl/loadbalancer/gen-loadbalancer.sh
Outdated
@@ -1,4 +1,25 @@ | |||
#!/bin/sh | |||
############################################################################# | |||
# Copyright (c) 2017 Balabit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please squash the style check and copyright commits ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can, but why?
it does two different things on two different modules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I meant not those two commits into one :)
You have currently 4 commits, from which 2 of them just for style check and copyright.
It would be nice to squash this modification into the original two commits (those are well separated).
The confgen: fixed coding style error and confgen: enable passing arguments to confgen external program as env into one, also the loadbalancer: added missing copyright headers and loadbalancer: added network load balancer destination into one.
I hope it make more sense like this :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair, i will do it :)
static void | ||
confgen_set_args_as_env(gpointer k, gpointer v, gpointer user_data) | ||
{ | ||
gchar buf[1024]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the 1024 is not enough ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we truncate the variable name, but it is fairly unlikely to have such a long option name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is fair enough.
{ | ||
gchar buf[1024]; | ||
g_snprintf(buf, sizeof(buf), "confgen_%s", (gchar *)k); | ||
setenv(buf, (gchar *)v, 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would happen if setenv
is not successful ?
If the environment variable exists, do we really want to override it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes we want to overwrite it
we can handle errors, but it is basically an out of memory case only, which is bad anyhow
EINVAL name is NULL, points to a string of length 0, or contains an '='
character.
ENOMEM Insufficient memory to add a new variable to the environment.
static void | ||
confgen_unset_args_from_env(gpointer k, gpointer v, gpointer user_data) | ||
{ | ||
gchar buf[1024]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the 1024 is not enough ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we truncate the variable name, but it is fairly unlikely to have such a long option name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is fair enough.
|
||
cfg_args_foreach(args, confgen_set_args_as_env, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: At least on documentation level it should be considered that in the name of the args the -
s are replaced with _
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point
echo ' filter {' | ||
echo -n ' "' | ||
echo -n $target_id | ||
echo -n '" == "$(% ${R_MSEC} ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we benefit from allowing other number source ? For example $SEQNUM
could also work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it could work.
@bazsi also suggested using HOST, but that is bit tricky to create a filter as there is not module for string, of course we can use comparison always. Though it would not balance well with many logs coming from one host. Probably that could be made configurable.
Either MSEC or SEQNUM could work, however we wanted something simple.
I would leave it as it is now, and if someone wants to enhance it they can send PR.
echo -n $target | ||
echo -n '" ' | ||
echo -n $TARGET_PARAMS | ||
#echo -n 'failover-servers("' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you remove this commented part of the script ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i intentionaly left it here as there is failover support in PE6, but not here, so anyone wanting to port it would find it useful.
Of couse it can be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather not include it here.
target_cnt=$(echo $TARGETS | wc -w) | ||
target_id=0 | ||
echo 'channel {' | ||
for target in $TARGETS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The MSEC
max value is a limit of the number of the target
s. In this case the script do not really need to create the extra channel
s.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not understand this limit, but if you ommit the channel definition the final flag would stop the msg processing not just for this but for other destination.
what do i miss?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there are MSEC + n
target, those n
targets won't be chosen. Of course it won't cause any issue, but it enlarges the configuration unnecessarily.
It would be a minor tweak not even creating them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check the code, it wont happen, unless they configure more then 2^128 servers destination :)
we do the modulo of the # of targets on MSEC and MSEC is a large number, even in 1 sec there are 1000 different value, so it should be ok up to a dozen target for sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @Kokan just wanted to clarify that MSEC
is not a large integer, it's a number between 0 and 999.
That is the reason why you may not want to generate more than 1000 channels/destinations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have any problems with the current implementation, we just wanted to let you know about this. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think that this would actually scale to more then a dozen (and also does not seem to be realistic) so we should be fine wit this :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tried this out in real life? Or any kind of emulation with high traffic ? It would be nice to see how balanced it gets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feri used a less efficient version (using regexp) in production, ask him for details.
scl/loadbalancer/plugin.conf
Outdated
@module confgen context(destination) name(genlb) exec("`scl-root`/loadbalancer/gen-loadbalancer.sh") | ||
|
||
|
||
block destination load-balancer(targets()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would include somehow in the name, that it is currently for network
destination only, and not a full-fledged general load balancer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
network-load-balancer is ok or maybe network-rr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer network-load-balancer
.
…variables Options can be set when invoking confgen external program. These options are passed as environment variables. Note that env variables are overwritten and cleared after the external execution. Also note that in option names dash(-) is converted to underscore (_). This comes handy as this way configuration can be generated not only dynamically, but also driven from the configuration. @module confgen context(destination) name(mygen) exec("gen.sh") And later that can be used as: mygen( option1(param1) option2("my other option") )
It implements a simple round-robin load balancing between multiple destination. Balancing is based on MSEC hashing where destinations share the same configuration except the destination address. The main purpose to make load balance configuration simple. It can be used as a simple network destination and all network parameters are recognized, the destination servers must be configured as a space separated list of host using the "targets" option: destination mydest { network-load-balancer( targets(server1 server2 server2) # mandatory option # additional network options can be set as well: transport(udp) port(3456) ) }; NOTE: as failover-server is not supported in this version it is left out. Otherwise nodes are used for fail-over servers to maintain availability. The idea and original configuration comes from Ferenc Sipos. Big kudos for the inspiration and for his persistence on pushing me to add this function on our flight from New York to Memphis, TN! Thx!
Build SUCCESS, the tests were executed on test branch: master and test suite: functions |
I fixed what I considered important, so feel free to merge it or enhance it further if you want |
Also extended confgen module:
confgen: enable passing arguments to confgen external program as env variables
This functionality probably addresses #1210 mostly.