The script KxSystems/kdb/e/mserve.q can be used to start a load-balancing kdb+ server. The primary server starts a number of secondary servers (in the same host). Clients then send requests to the primary server which, transparently to the client, chooses a secondary server with low CPU load, and forwards the request there.

This set-up is useful for read operations, such as queries on historical databases. Each query is executed in one of the secondary threads, hence writes are not replicated.

## Starting the primary server

The arguments are the number of secondary servers, and the name of a q script that will be executed by the secondary servers at start-up. Typically this script will read in a database from disk into memory.

$q mserve.q -p 5001 2 startup.q  ## Client request In the client, connect to the server with hopen q)h: hopen :localhost:5001  Synchronous messages are executed at the primary server. q)h "xs: til 9" q)h "xs" 0 1 2 3 4 5 6 7 8  Asynchronous messages are forwarded to one of the secondary servers, transparently to the client. The code below issues an asynchronous request, then blocks on the handle waiting for a result to be returned. This is called deferred synchronous. q)(neg h) "select sym,price from trade where size > 50000" ; h[]  Deferred synchronous requests can also be made from non-q clients. For example, the example grid viewer code can be modified to issue a deferred synchronous request rather than a synchronous request by sending an async request and blocking on the handle in exactly the same way. The line model.setFlip((c.Flip) c.k(query));  should be modified to c.ks(query); model.setFlip((c.Flip) c.k());  ## Source code The complete source code for mserve.q is quite short, reproduced here for convenience. / start secondary servers {value"\\q ",.z.x[1]," -p ",string x}each p:(value"\\p")+1+til"I"$.z.x 0;

/ unix (comment out for windows)
\sleep 1

/ connect to secondary servers
h:neg hopen each p;h@\:".z.pc:{exit 0}";h!:()

/ fields queries. assign query to least busy secondary server
.z.ps:{\$[(w:neg .z.w)in key h;[h[w;0]x;h[w]:1_h w];                    /response
[h[a?:min a:count each h],:w;a("{(neg .z.w)@[value;x;error]}";x)]]}  /request