The default Go implementation of
sync.RWMutex does not scale well
to multiple cores, as all readers contend on the same memory location
when they all try to atomically increment it. This gist explores an
n
-way RWMutex, also known as a "big reader" lock, which gives each
CPU core its own RWMutex. Readers take only a read lock local to their
core, whereas writers must take all locks in order.
import subprocess | |
import time | |
import sys | |
def parent(): | |
p = subprocess.Popen(['python', './testp.py', '--child'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) |
package main | |
import( | |
"fmt" | |
"runtime" | |
"io/ioutil" | |
"bytes" | |
"strings" | |
) |
package redis | |
import ( | |
"fmt" | |
"github.com/garyburd/redigo/redis" | |
) | |
// Batch represents a set of batched results, either a transaction or just send/receive. | |
// |
package main | |
import( | |
"fmt" | |
"time" | |
"github.com/EverythingMe/go-disque/disque" | |
"github.com/garyburd/redigo/redis" | |
) |
package main | |
import ( | |
"fmt" | |
"github.com/EverythingMe/inbloom/go/inbloom" | |
"net/http" | |
) | |
var vocabulary = []string{"foo", "bar", "baz", "hey", "yo", "go"} |
package foo | |
import ( | |
"testing" | |
) | |
type Foo struct { | |
a string | |
b int | |
c float32 |
A quick guide to write a very very simple "ECHO" style module to redis and load it. It's not really useful of course, but the idea is to illustrate how little boilerplate it takes.
Step 1: open your favorite editor and write/paste the following code in a file called module.c
#include "redismodule.h"
/* ECHO <string> - Echo back a string sent from the client */
int EchoCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
// A serializer prototype - you serialize by calling Write N times. | |
// the key type is determined on registration so not needed here | |
// the list size will be determined by redis when you exit, based on the number of times you called write() | |
int (*Serialize)(RedisModuleCtx *ctx, RedisModuleObjectWriter *out, RedisModuleKey *k) | |
// you deserialize by calling Read and reading one object at a time. | |
// numElements is passed so the user can preallocate stuff in advance | |
int (*Deserialize)(RedisModuleCtx *ctx, RedisModuleObjectReader *in, RedisModuleString *keyName, size_t numElements) |
Redis is a very sophisticated data structure server, that can be used as a powerful in-memory database. However, if you look at redis as database per-se, it only has primary keys. There is no native way to ask redis for something like "what are the names of users over 18 who have visited my website yesterday?".
If you're familiar with traditional relational databases, this is usually done by creating an index on the relevant columns in your table, allowing to efficiently add complex WHERE clauses to your query. Such an index is called a Secondary Index.
While it is possible (and done by many many people) to implement these indexes on top of redis manually, doing them right and in a performant way is hard.