Yet another in-memory key/value storage written in Go.
Simple key/value storage. Based on Striped hashmap algorithm.
- Concurrency safe
- Fast
- Written in pure Go, means could be used in any place where Go could be run
- Could be used as embedded storage
- Could be run as standalone server
Server commands:
- PING -- Test command. Returns "Pong!".
Hash commands:
- SET <key> <value> -- Set create or update <key> with <value>.
- GET <key> -- Get value of the <key>.
- DEL <key> -- Delete key <key>.
Collection commands:
- CGET <collection name> -- Change user's collection.
- CADD <collection name> -- Create new collection.
####Build server:
make ghost-server
####Run server:
ghost -host localhost -port 6869
####Build:
make ghost-benchmark
Usage of ghost-benchmark:
-clients int
Number of paralel connections (default 50)
-embedded
Test embedded storage
-host string
Server hostname (default "localhost")
-keyrange int
Use random keys for SET/GET (default 100)
-pooltimeout int
Client PoolTimeout option (default 10)
-port int
Server port (default 6869)
-requests int
Total number of requests (default 10000)
-size int
Data size of SET/GET value in bytes (default 2)
-socket string
Listen to unix socket
package main
import (
"fmt"
"github.com/alexyer/ghost/client"
)
func main() {
// Create new client and connect to the Ghost server.
ghost := client.New(&client.Options{
Addr: "localhost:6869",
})
ghost.Set("key1", "val2") // Set key
res, err := ghost.Get("key1") // Get key
ghost.Del("key1") // Del key
ghost.CAdd("new-collection") // Create new collection
ghost.CGet("new-collection") // Change client collection
}
Now you can use a simple cli to test or play with data. All the current commands are supported. Cli works only if ghost-server exists on provided address.
####Build:
make ghost-cli
####Run cli:
ghost-cli -host localhost -port 6869
> ping # will test the connection
Pong!
> set hello world # will set value "world" to key "hello"
OK
> get hello # will get the value stored with key "hello"
world
> del hello # will delete the value stored with key "hello"
OK
> cadd mars # will add new "mars" collection
OK
> cget mars # will select "mars" collection
OK
> set "few words key" "few words value" # if few words in value or keys is needed surround it with quotes
OK
> get "few words key"
few words value
> set song "riders on the storm" # only one argument could be in quotes if needed
OK
> get song
riders on the storm
> set "another song" stairway # other order is possible
OK
> get "another song"
stairway
# cli also supports two utility command:
> help # to get the help message
> quit # to correct way out of cli
Ghost hashmap
BenchmarkSet-4 500000 4625 ns/op
BenchmarkGet-4 10000000 101 ns/op
BenchmarkDel-4 20000000 75.1 ns/op
Ghost concurrent hashmap
BenchmarkParallelSet-4 300000 3680 ns/op
BenchmarkParallelSet8-4 500000 4050 ns/op
BenchmarkParallelSet64-4 500000 4107 ns/op
BenchmarkParallelSet128-4 500000 4132 ns/op
BenchmarkParallelSet1024-4 300000 4256 ns/op
BenchmarkParallelGet-4 20000000 116 ns/op
BenchmarkParallelGet8-4 20000000 133 ns/op
BenchmarkParallelGet64-4 20000000 136 ns/op
BenchmarkParallelGet128-4 20000000 142 ns/op
BenchmarkParallelGet1024-4 20000000 137 ns/op
BenchmarkParallelDel-4 10000000 122 ns/op
BenchmarkParallelDel8-4 10000000 152 ns/op
BenchmarkParallelDel64-4 10000000 154 ns/op
BenchmarkParallelDel128-4 10000000 154 ns/op
BenchmarkParallelDel1024-4 10000000 156 ns/op
Native hashmap
BenchmarkNativeSet-4 3000000 338 ns/op
BenchmarkNativeGet-4 30000000 41.3 ns/op
BenchmarkNativeDel-4 100000000 15.5 ns/op
package main
import (
"fmt"
"github.com/alexyer/ghost"
)
func main() {
//Storage
storage := ghost.GetStorage() // Get storage instance
storage.AddCollection("newcollection") // Create new collection
mainCollection := storage.GetCollection("main") // Get existing collection
storage.DelCollection("newcollection") // Delete collection
// Collections
mainCollection.Set("somekey", "42") // Set item
val, _ := mainCollection.Get("somekey") // Get item from Collection
fmt.Println(val)
mainCollection.Del("somekey") // Delete item
}
It's learing project, so there are possible a lot of issues, espesially in concurrent code, so any improvements, critics or propsals are highly appretiated.