Skip to content
This repository has been archived by the owner on Jul 22, 2020. It is now read-only.

Commit

Permalink
feat: add redis Unix Domain Socket support for high performance (#26)
Browse files Browse the repository at this point in the history
* feat: add redis Unix Domain Socket support for high performance
* feat: add redis unix domain socket support for api.js
* wording enhancements
  • Loading branch information
sunnygleason authored Feb 22, 2019
1 parent 4b61005 commit e6b412f
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 5 deletions.
91 changes: 91 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,94 @@ and if desired for UI testing:
```bash
$ ./multinode-demo/client.sh --tx_count 40 --threads 2 -z 400
```

## High Performance Use Cases

### Redis via Unix Domain Socket

Redis is known as a very fast in-memory data structure server. To keep up with Solana
speeds, it may be useful to enable Unix Domain Socket communication for added performance
(potentially 10-40% or more depending on the operations).

Add configuration similar to the following to your `/etc/redis/redis.conf` (or equivalent):
```
unixsocket /var/run/redis/redis-server.sock
unixsocketperm 770
```

Increasing max socket connections on Linux may also prove useful:
```bash
sudo sysctl net.core.somaxconn=16384
```

Remember to restart `redis-server` to pick up the new configuration:
```bash
sudo service redis-server restart
```

Ensure that your API unix user is in the same group as your `redis` user so it can read
the file. For example, you may need to do something like this:
```bash
sudo chgrp -R ubuntu /var/run/redis
```

Finally, update the redis section of `api/config.js` to enable the `path` configuration
which takes precedence over the host/port options:
```js
...
redis: {
...
path: '/var/run/redis/redis-server.sock',
},
...
```

If you would like to test Redis performance, the `redis-benchmark` tool is very handy
for quick sanity checks while tuning configuration.

Results using localhost TCP socket:
```bash
$ redis-benchmark -q -n 2000000 -c 1000 -P 40
PING_INLINE: 567215.00 requests per second
PING_BULK: 1021450.50 requests per second
SET: 587026.69 requests per second
GET: 741839.75 requests per second
INCR: 619195.06 requests per second
LPUSH: 671366.19 requests per second
RPUSH: 810701.25 requests per second
LPOP: 473372.78 requests per second
RPOP: 769230.81 requests per second
SADD: 925925.88 requests per second
HSET: 693721.81 requests per second
SPOP: 914494.75 requests per second
LPUSH (needed to benchmark LRANGE): 547495.19 requests per second
LRANGE_100 (first 100 elements): 34660.24 requests per second
LRANGE_300 (first 300 elements): 9543.71 requests per second
LRANGE_500 (first 450 elements): 6180.72 requests per second
LRANGE_600 (first 600 elements): 4716.88 requests per second
MSET (10 keys): 123137.54 requests per second
```

Results using Unix Domain Socket:
```bash
$ redis-benchmark -q -n 2000000 -c 1000 -P 40 -s /var/run/redis/redis-server.sock
PING_INLINE: 1038421.62 requests per second
PING_BULK: 1673640.12 requests per second
SET: 896459.00 requests per second
GET: 1175779.00 requests per second
INCR: 1107419.75 requests per second
LPUSH: 814995.94 requests per second
RPUSH: 768049.12 requests per second
LPOP: 775494.38 requests per second
RPOP: 884564.38 requests per second
SADD: 1047120.44 requests per second
HSET: 758437.62 requests per second
SPOP: 1275510.25 requests per second
LPUSH (needed to benchmark LRANGE): 810372.81 requests per second
LRANGE_100 (first 100 elements): 58491.50 requests per second
LRANGE_300 (first 300 elements): 12462.15 requests per second
LRANGE_500 (first 450 elements): 7449.32 requests per second
LRANGE_600 (first 600 elements): 4019.78 requests per second
MSET (10 keys): 120279.05 requests per second
```

6 changes: 5 additions & 1 deletion api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ const port = 3001;
const MINUTE_MS = 60 * 1000;

function getClient() {
return redis.createClient(config.redis);
let props = config.redis.path
? {path: config.redis.path}
: {host: config.redis.host, port: config.redis.port};

return redis.createClient(props);
}

expressWs(app);
Expand Down
1 change: 1 addition & 0 deletions api/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ export default {
redis: {
host: '127.0.0.1',
port: 6379,
// path: '/var/run/redis/redis-server.sock',
},
};
9 changes: 5 additions & 4 deletions api/inbound-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,11 @@ class BridgeFn {

class RedisHandler {
constructor(props) {
this.innerClient = redis.createClient({
host: props.host,
port: props.port,
});
const config = props.path
? {path: props.path}
: {host: props.host, port: props.port};

this.innerClient = redis.createClient(config);

this.process = this.process.bind(this);
}
Expand Down

0 comments on commit e6b412f

Please sign in to comment.