Redis Durability Test
5 Dec 2015
I'm using a custom-compiled Redis as detailed here.
Wow. Redis inserts are crazy fast. Of course, with those crazy fast inserts, obviously a lot of buffering is going on, though.
As with all the previous durability tests, let's turn on our consumer SSD's write-through feature (see the first post on the page for details):
# ./set-write-through.sh
In root's home dir, here is a script to kill redis, kill-redis.sh
.
#!/bin/bash set -e set -o pipefail set -u PGPID=$(cat /usr/local/redis-3.0.5/var/redis_6379.pid) kill -9 ${PGPID}
In your regular user's home directory, here is a script to get the integers
successfully written to Redis, get-last-written.sh
.
#!/bin/bash set -u set -e set -o pipefail # Interesting. The max integer is at the lowest offset echo "max integer" /usr/local/redis-3.0.5/bin/redis-cli lindex test_ints 0 # ...and the min integer is at the highest offset MX=$(/usr/local/redis-3.0.5/bin/redis-cli llen test_ints) MX=$(( MX - 1 )) echo "min integer" /usr/local/redis-3.0.5/bin/redis-cli lindex test_ints ${MX} echo "number of integers" /usr/local/redis-3.0.5/bin/redis-cli llen test_ints
In your regular user's go/src directory, (such as
${HOME}/go/src/github.com/foo/redis-durability/insert-ints)
,
create this main.go file:
package main import ( "fmt" "os" "github.com/mediocregopher/radix.v2/redis" ) func main() { client, err := redis.Dial("tcp", "localhost:6379") defer closeClient(client) if err != nil { fmt.Fprintf(os.Stderr, "Could not connect to redis: %v\n", err) os.Exit(1) } err = client.Cmd("del", "test_ints").Err if err != nil { fmt.Fprintf(os.Stderr, "Could not delete test_ints array: %v\n", err) os.Exit(1) } i := 0 for { i++ err = client.Cmd("lpush", "test_ints", i).Err if err != nil { fmt.Fprintf(os.Stderr, "Did not insert %d\n", i) os.Exit(1) } fmt.Printf("inserted %d\n", i) } } func closeClient(client *redis.Client) { if client != nil { client.Close() } }
Build the above go file.
$ cd go/src/github.com/manniwood/redis-durability/insert-ints $ go get github.com/mediocregopher/radix.v2 $ go build
Now you've got everything you need.
In a root terminal, set your consumer hard drive to not cache writes, but to write them to permantent storage immediately. (With most consumer hard drives, this setting will be forgotten after a reboot, so don't worry about wearing out your hard drive fater.):
# ./set-write-through.sh
Next, be sure Redis is running. Also run this command in a root terminal:
# systemctl start redis-6379
Let's run our go command to insert ints into Redis in a loop. This can be run in a regular user's terminal:
$ ./insert-ints
Now let's return to our root terminal and kill Redis while it is running:
# ./kill-redis.sh # systemctl status redis-6379
The second command, above, should show us that PostgreSQL was killed.
Also, back in your regular user's terminal, you should see that the go program exited like this:
... inserted 31876 inserted 31877 inserted 31878 inserted 31879 Did not insert 31880
Now let's prove to ourselves that Redis saved all of our writes to disc... or not!
# systemctl start redis-6379 # ./get-last-written.sh max integer "659" min integer "1" number of integers (integer) 659
With default durability settings, Redis works as advertised. A lot of buffering happens with writes, and a small percentage of our writes made it into Redis.