godis

package module
v1.2.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 17, 2021 License: GPL-3.0 Imports: 25 Imported by: 1

README

Godis

license Build Status Coverage Status Go Report Card Go Reference

中文版

Godis is a simple implementation of Redis Server, which intents to provide an example of writing a high concurrent middleware using golang.

Gods implemented most features of redis, including 5 data structures, ttl, publish/subscribe, geo and AOF persistence.

Godis can run as a server side cluster which is transparent to client. You can connect to any node in the cluster to access all data in the cluster:

If you could read Chinese, you can find more details in My Blog.

Get Started

You can get runnable program in the releases of this repository, which supports Linux and Darwin system.

./godis-darwin
./godis-linux

You could use redis-cli or other redis client to connect godis server, which listens on 0.0.0.0:6399 on default mode.

The program will try to read config file path from environment variable CONFIG.

If environment variable is not set, then the program try to read redis.conf in the working directory.

If there is no such file, then the program will run with default config.

cluster mode

Godis can work in cluster mode, please append following lines to redis.conf file

peers localhost:7379,localhost:7389 // other node in cluster
self  localhost:6399 // self address

We provide node1.conf and node2.conf for demonstration. use following command line to start a two-node-cluster:

CONFIG=node1.conf ./godis-darwin &
CONFIG=node2.conf ./godis-darwin &

Connect to a node in the cluster to access all data in the cluster:

redis-cli -p 6399

Commands

Supported Commands:

  • Keys
    • del
    • expire
    • expireat
    • pexpire
    • pexpireat
    • ttl
    • pttl
    • persist
    • exists
    • type
    • rename
    • renamenx
  • Server
    • flushdb
    • flushall
    • keys
    • bgrewriteaof
  • String
    • set
    • setnx
    • setex
    • psetex
    • mset
    • mget
    • msetnx
    • get
    • getset
    • incr
    • incrby
    • incrbyfloat
    • decr
    • decrby
  • List
    • lpush
    • lpushx
    • rpush
    • rpushx
    • lpop
    • rpop
    • rpoplpush
    • lrem
    • llen
    • lindex
    • lset
    • lrange
  • Hash
    • hset
    • hsetnx
    • hget
    • hexists
    • hdel
    • hlen
    • hmget
    • hmset
    • hkeys
    • hvals
    • hgetall
    • hincrby
    • hincrbyfloat
  • Set
    • sadd
    • sismember
    • srem
    • scard
    • smembers
    • sinter
    • sinterstore
    • sunion
    • sunionstore
    • sdiff
    • sdiffstore
    • srandmember
  • SortedSet
    • zadd
    • zscore
    • zincrby
    • zrank
    • zcount
    • zrevrank
    • zcard
    • zrange
    • zrevrange
    • zrangebyscore
    • zrevrangebyscore
    • zrem
    • zremrangebyscore
    • zremrangebyrank
  • Pub / Sub
    • publish
    • subscribe
    • unsubscribe
  • Geo
    • GeoAdd
    • GeoPos
    • GeoDist
    • GeoHash
    • GeoRadius
    • GeoRadiusByMember

Read My Code

If you want to read my code in this repository, here is a simple guidance.

  • cmd: only the entry point
  • config: config parser
  • interface: some interface definitions
  • lib: some utils, such as logger, sync utils and wildcard

I suggest focusing on the following directories:

  • tcp: the tcp server
  • redis: the redis protocol parser
  • datastruct: the implements of data structures
    • dict: a concurrent hash map
    • list: a linked list
    • lock: it is used to lock keys to ensure thread safety
    • set: a hash set based on map
    • sortedset: a sorted set implements based on skiplist
  • db: the implements of the redis db
    • db.go: the basement of database
    • router.go: it find handler for commands
    • keys.go: handlers for keys commands
    • string.go: handlers for string commands
    • list.go: handlers for list commands
    • hash.go: handlers for hash commands
    • set.go: handlers for set commands
    • sortedset.go: handlers for sorted set commands
    • pubsub.go: implements of publish / subscribe
    • aof.go: implements of AOF persistence and rewrite

License

This project is licensed under the GPL license.

Documentation

Overview

Package godis is a memory database with redis compatible interface

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Auth

func Auth(db *DB, c redis.Connection, args [][]byte) redis.Reply

Auth validate client's password

func BGRewriteAOF

func BGRewriteAOF(db *DB, args [][]byte) redis.Reply

BGRewriteAOF asynchronously rewrites Append-Only-File

func Decr

func Decr(db *DB, args [][]byte) redis.Reply

Decr decrements the integer value of a key by one

func DecrBy

func DecrBy(db *DB, args [][]byte) redis.Reply

DecrBy decrements the integer value of a key by onedecrement

func Del

func Del(db *DB, args [][]byte) redis.Reply

Del removes a key from db

func EntityToCmd

func EntityToCmd(key string, entity *DataEntity) *reply.MultiBulkReply

EntityToCmd serialize data entity to redis command

func Exists

func Exists(db *DB, args [][]byte) redis.Reply

Exists checks if a is existed in db

func Expire

func Expire(db *DB, args [][]byte) redis.Reply

Expire sets a key's time to live in seconds

func ExpireAt

func ExpireAt(db *DB, args [][]byte) redis.Reply

ExpireAt sets a key's expiration in unix timestamp

func FlushAll

func FlushAll(db *DB, args [][]byte) redis.Reply

FlushAll removes all data in all db

func FlushDB

func FlushDB(db *DB, args [][]byte) redis.Reply

FlushDB removes all data in current db

func GeoAdd

func GeoAdd(db *DB, args [][]byte) redis.Reply

GeoAdd add a location into SortedSet

func GeoDist

func GeoDist(db *DB, args [][]byte) redis.Reply

GeoDist returns the distance between two locations

func GeoHash

func GeoHash(db *DB, args [][]byte) redis.Reply

GeoHash return geo-hash-code of given position

func GeoPos

func GeoPos(db *DB, args [][]byte) redis.Reply

GeoPos returns location of a member

func GeoRadius

func GeoRadius(db *DB, args [][]byte) redis.Reply

GeoRadius returns members within max distance of given point

func GeoRadiusByMember

func GeoRadiusByMember(db *DB, args [][]byte) redis.Reply

GeoRadiusByMember returns members within max distance of given member's location

func Get

func Get(db *DB, args [][]byte) redis.Reply

Get returns string value bound to the given key

func GetSet

func GetSet(db *DB, args [][]byte) redis.Reply

GetSet sets value of a string-type key and returns its old value

func HDel

func HDel(db *DB, args [][]byte) redis.Reply

HDel deletes a hash field

func HExists

func HExists(db *DB, args [][]byte) redis.Reply

HExists checks if a hash field exists

func HGet

func HGet(db *DB, args [][]byte) redis.Reply

HGet gets field value of hash table

func HGetAll

func HGetAll(db *DB, args [][]byte) redis.Reply

HGetAll gets all key-value entries in hash table

func HIncrBy

func HIncrBy(db *DB, args [][]byte) redis.Reply

HIncrBy increments the integer value of a hash field by the given number

func HIncrByFloat

func HIncrByFloat(db *DB, args [][]byte) redis.Reply

HIncrByFloat increments the float value of a hash field by the given number

func HKeys

func HKeys(db *DB, args [][]byte) redis.Reply

HKeys gets all field names in hash table

func HLen

func HLen(db *DB, args [][]byte) redis.Reply

HLen gets number of fields in hash table

func HMGet

func HMGet(db *DB, args [][]byte) redis.Reply

HMGet gets multi fields in hash table

func HMSet

func HMSet(db *DB, args [][]byte) redis.Reply

HMSet sets multi fields in hash table

func HSet

func HSet(db *DB, args [][]byte) redis.Reply

HSet sets field in hash table

func HSetNX

func HSetNX(db *DB, args [][]byte) redis.Reply

HSetNX sets field in hash table only if field not exists

func HVals

func HVals(db *DB, args [][]byte) redis.Reply

HVals gets all field value in hash table

func Incr

func Incr(db *DB, args [][]byte) redis.Reply

Incr increments the integer value of a key by one

func IncrBy

func IncrBy(db *DB, args [][]byte) redis.Reply

IncrBy increments the integer value of a key by given value

func IncrByFloat

func IncrByFloat(db *DB, args [][]byte) redis.Reply

IncrByFloat increments the float value of a key by given value

func Keys

func Keys(db *DB, args [][]byte) redis.Reply

Keys returns all keys matching the given pattern

func LIndex

func LIndex(db *DB, args [][]byte) redis.Reply

LIndex gets element of list at given list

func LLen

func LLen(db *DB, args [][]byte) redis.Reply

LLen gets length of list

func LPop

func LPop(db *DB, args [][]byte) redis.Reply

LPop removes the first element of list, and return it

func LPush

func LPush(db *DB, args [][]byte) redis.Reply

LPush inserts element at head of list

func LPushX

func LPushX(db *DB, args [][]byte) redis.Reply

LPushX inserts element at head of list, only if list exists

func LRange

func LRange(db *DB, args [][]byte) redis.Reply

LRange gets elements of list in given range

func LRem

func LRem(db *DB, args [][]byte) redis.Reply

LRem removes element of list at specified index

func LSet

func LSet(db *DB, args [][]byte) redis.Reply

LSet puts element at specified index of list

func MGet

func MGet(db *DB, args [][]byte) redis.Reply

MGet get multi key-value from database

func MSet

func MSet(db *DB, args [][]byte) redis.Reply

MSet sets multi key-value in database

func MSetNX

func MSetNX(db *DB, args [][]byte) redis.Reply

MSetNX sets multi key-value in database, only if none of the given keys exist

func PExpire

func PExpire(db *DB, args [][]byte) redis.Reply

PExpire sets a key's time to live in milliseconds

func PExpireAt

func PExpireAt(db *DB, args [][]byte) redis.Reply

PExpireAt sets a key's expiration in unix timestamp specified in milliseconds

func PSetEX

func PSetEX(db *DB, args [][]byte) redis.Reply

PSetEX set a key's time to live in milliseconds

func PTTL

func PTTL(db *DB, args [][]byte) redis.Reply

PTTL returns a key's time to live in milliseconds

func Persist

func Persist(db *DB, args [][]byte) redis.Reply

Persist removes expiration from a key

func Ping

func Ping(db *DB, args [][]byte) redis.Reply

Ping the server

func RPop

func RPop(db *DB, args [][]byte) redis.Reply

RPop removes last element of list then return it

func RPopLPush

func RPopLPush(db *DB, args [][]byte) redis.Reply

RPopLPush pops last element of list-A then insert it to the head of list-B

func RPush

func RPush(db *DB, args [][]byte) redis.Reply

RPush inserts element at last of list

func RPushX

func RPushX(db *DB, args [][]byte) redis.Reply

RPushX inserts element at last of list only if list exists

func Rename

func Rename(db *DB, args [][]byte) redis.Reply

Rename a key

func RenameNx

func RenameNx(db *DB, args [][]byte) redis.Reply

RenameNx a key, only if the new key does not exist

func SAdd

func SAdd(db *DB, args [][]byte) redis.Reply

SAdd adds members into set

func SCard

func SCard(db *DB, args [][]byte) redis.Reply

SCard gets the number of members in a set

func SDiff

func SDiff(db *DB, args [][]byte) redis.Reply

SDiff subtracts multiple sets

func SDiffStore

func SDiffStore(db *DB, args [][]byte) redis.Reply

SDiffStore subtracts multiple sets and store the result in a key

func SInter

func SInter(db *DB, args [][]byte) redis.Reply

SInter intersect multiple sets

func SInterStore

func SInterStore(db *DB, args [][]byte) redis.Reply

SInterStore intersects multiple sets and store the result in a key

func SIsMember

func SIsMember(db *DB, args [][]byte) redis.Reply

SIsMember checks if the given value is member of set

func SMembers

func SMembers(db *DB, args [][]byte) redis.Reply

SMembers gets all members in a set

func SRandMember

func SRandMember(db *DB, args [][]byte) redis.Reply

SRandMember gets random members from set

func SRem

func SRem(db *DB, args [][]byte) redis.Reply

SRem removes a member from set

func SUnion

func SUnion(db *DB, args [][]byte) redis.Reply

SUnion adds multiple sets

func SUnionStore

func SUnionStore(db *DB, args [][]byte) redis.Reply

SUnionStore adds multiple sets and store the result in a key

func Set

func Set(db *DB, args [][]byte) redis.Reply

Set sets string value and time to live to the given key

func SetEX

func SetEX(db *DB, args [][]byte) redis.Reply

SetEX sets string and its ttl

func SetNX

func SetNX(db *DB, args [][]byte) redis.Reply

SetNX sets string if not exists

func TTL

func TTL(db *DB, args [][]byte) redis.Reply

TTL returns a key's time to live in seconds

func Type

func Type(db *DB, args [][]byte) redis.Reply

Type returns the type of entity, including: string, list, hash, set and zset

func ZAdd

func ZAdd(db *DB, args [][]byte) redis.Reply

ZAdd adds member into sorted set

func ZCard

func ZCard(db *DB, args [][]byte) redis.Reply

ZCard gets number of members in sortedset

func ZCount

func ZCount(db *DB, args [][]byte) redis.Reply

ZCount gets number of members which score within given range

func ZIncrBy

func ZIncrBy(db *DB, args [][]byte) redis.Reply

ZIncrBy increments the score of a member

func ZRange

func ZRange(db *DB, args [][]byte) redis.Reply

ZRange gets members in range, sort by score in ascending order

func ZRangeByScore

func ZRangeByScore(db *DB, args [][]byte) redis.Reply

ZRangeByScore gets members which score within given range, in ascending order

func ZRank

func ZRank(db *DB, args [][]byte) redis.Reply

ZRank gets index of a member in sortedset, ascending order, start from 0

func ZRem

func ZRem(db *DB, args [][]byte) redis.Reply

ZRem removes given members

func ZRemRangeByRank

func ZRemRangeByRank(db *DB, args [][]byte) redis.Reply

ZRemRangeByRank removes members within given indexes

func ZRemRangeByScore

func ZRemRangeByScore(db *DB, args [][]byte) redis.Reply

ZRemRangeByScore removes members which score within given range

func ZRevRange

func ZRevRange(db *DB, args [][]byte) redis.Reply

ZRevRange gets members in range, sort by score in descending order

func ZRevRangeByScore

func ZRevRangeByScore(db *DB, args [][]byte) redis.Reply

ZRevRangeByScore gets number of members which score within given range, in descending order

func ZRevRank

func ZRevRank(db *DB, args [][]byte) redis.Reply

ZRevRank gets index of a member in sortedset, descending order, start from 0

func ZScore

func ZScore(db *DB, args [][]byte) redis.Reply

ZScore gets score of a member in sortedset

Types

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB stores data and execute user's commands

func MakeDB

func MakeDB() *DB

MakeDB create DB instance and start it

func (*DB) AddAof

func (db *DB) AddAof(args *reply.MultiBulkReply)

AddAof send command to aof goroutine through channel

func (*DB) AfterClientClose

func (db *DB) AfterClientClose(c redis.Connection)

AfterClientClose does some clean after client close connection

func (*DB) Close

func (db *DB) Close()

Close graceful shutdown database

func (*DB) Exec

func (db *DB) Exec(c redis.Connection, cmdArgs [][]byte) (result redis.Reply)

Exec executes command parameter `cmdArgs` contains command and its arguments, for example: "set key value"

func (*DB) Expire

func (db *DB) Expire(key string, expireTime time.Time)

Expire sets TTL of key

func (*DB) Flush

func (db *DB) Flush()

Flush clean database

func (*DB) GetEntity

func (db *DB) GetEntity(key string) (*DataEntity, bool)

GetEntity returns DataEntity bind to given key

func (*DB) IsExpired

func (db *DB) IsExpired(key string) bool

IsExpired check whether a key is expired

func (*DB) Lock

func (db *DB) Lock(key string)

Lock locks key for writing (exclusive lock)

func (*DB) Locks

func (db *DB) Locks(keys ...string)

Locks lock keys for writing (exclusive lock)

func (*DB) Persist

func (db *DB) Persist(key string)

Persist cancel TTL of key

func (*DB) PutEntity

func (db *DB) PutEntity(key string, entity *DataEntity) int

PutEntity a DataEntity into DB

func (*DB) PutIfAbsent

func (db *DB) PutIfAbsent(key string, entity *DataEntity) int

PutIfAbsent insert an DataEntity only if the key not exists

func (*DB) PutIfExists

func (db *DB) PutIfExists(key string, entity *DataEntity) int

PutIfExists edit an existing DataEntity

func (*DB) RLock

func (db *DB) RLock(key string)

RLock locks key for read (shared lock)

func (*DB) RLocks

func (db *DB) RLocks(keys ...string)

RLocks lock keys for read (shared lock)

func (*DB) RUnLock

func (db *DB) RUnLock(key string)

RUnLock release shared lock

func (*DB) RUnLocks

func (db *DB) RUnLocks(keys ...string)

RUnLocks release shared locks

func (*DB) Remove

func (db *DB) Remove(key string)

Remove the given key from db

func (*DB) Removes

func (db *DB) Removes(keys ...string) (deleted int)

Removes the given keys from db

func (*DB) UnLock

func (db *DB) UnLock(key string)

UnLock release exclusive lock

func (*DB) UnLocks

func (db *DB) UnLocks(keys ...string)

UnLocks release exclusive locks

type DataEntity

type DataEntity struct {
	Data interface{}
}

DataEntity stores data bound to a key, including a string, list, hash, set and so on

Directories

Path Synopsis
Package cluster provides a server side cluster which is transparent to client.
Package cluster provides a server side cluster which is transparent to client.
datastruct
set
interface
db
tcp
lib
redis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL