Coder Social home page Coder Social logo

kasvith / kache Goto Github PK

View Code? Open in Web Editor NEW
350.0 20.0 26.0 303 KB

A simple in memory cache written using go

Home Page: https://kasvith.github.io/kache

License: MIT License

Go 99.68% Shell 0.32%
go inmemory-db from-scratch tcp database nosql-database nosql golang resp sockets

kache's Introduction

kache

A simple and a flexible in memory cache

Build Status Build Status Build status Go Report Card HitCount codecov GitHub

gopher is looking at kache

What is kache

kache aims to develop a redis compatible in memory db with golang. Currently kache is powered up with RESP Protocol. kache also supports simple text protocol so you can issue commands to kache using netcat or telnet as you please. kache has powered with many features managing a simple codebase with golang.

Roadmap

  • Kache Server
  • Basic Commands as a POC
  • Cluster Mode
  • Pub/Sub Pattern
  • Snapshots of data
  • Kache CLI
  • Client Libraries for popular languages
  • Documentation
  • Security
  • Improved data Structures
  • Website

kache is a compiled program, download the one for your platform and extract the package to a directory you wish.

Go to that directory, open a command prompt and run the kache executable like

  • ./kache if you are on linux or mac
  • .\kache if you are on windows

This will start the application and port 7088 will be open by default.

Try to open telnet or netcat then

$: nc localhost 7088
ping

If you get the +PONG kache is working as expected.

Default configuration file can be found in config/kache-default.toml

kache can produce logs as you wish, in addition to default format it supports

  • json
  • logfmt

To run with a custom config file do

./kache --config=path/to/config/file.toml

Synopsis

A fast and a flexible in memory database built with go

kache [flags]

Options

      --config string    configuration file
  -d, --debug            output debug information
  -h, --help             help for kache
      --host string      host for running application (default "127.0.0.1")
      --logfile string   application log file
      --logging          set application logs (default true)
      --logtype string   kache can output logs in different formats like json or logfmt. The default one is custom to kache. (default "default")
      --maxClients int   max connections can be handled (default 10000)
      --maxTimeout int   max timeout for clients(in seconds) (default 120)
  -p, --port int         port for running application (default 7088)
  -v, --verbose          verbose output

Development

Prerequisites

  • Go 1.10.+

Installing mage

mage is the build tool we use for build kache. To install mage

Setting up workspace

  • Fork the repo
  • Go to your GOPATH if you don't know about it learn from here
  • Create a directory github.com/kasvith
  • Clone the repo into that directory and cd to it

Make sure you have an active internet connection as for the first time it will download some depedencies.

Build the kache

  • mage vendor will install all the dependencies of the project(will take some time)
  • mage kache will produce the binary of the kache in bin directory
  • mage kachecli will produce the binary of the kache-cli in bin directory

Other options

  • mage check will run gofmt, goimports, go vet and all tests with 32 bit platform including
  • mage fmt will run only gofmt on the code, will warn you when code has format errors
  • mage vet will reports suspicious constructs
  • mage imports will check import errors
  • mage test will run a unit test with defaults
  • mage test386 will run a test in 32-bit mode
  • mage testrace will run a test with race conditions enabled
  • mage -l for list all commands

Special note : According to your environment executable will be built, for windows users it will need to add .exe to the end of -o flag like go build -o bin/kache.exe ./cmd/kache

Contributions

kache is an opensource project. Contributions are welcome

  • Fork the repo and star it โญ
  • Open issues ๐Ÿ’ฅ
  • Raise PRs for issues โœ‹
  • Help on documentation ๐Ÿ“„
  • Slack

kache's People

Contributors

bigjk avatar chyroc avatar kasvith avatar nakshay avatar vic3lord avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kache's Issues

Odbc

Sorry , can kache run on odbc? And can it export to any other rdbms like mssql,orcale, etc?

Uppercase redis command is not supported

Description
Uppercase redis command is not supported

Steps to reproduce the behavior:
start kache

./bin/kache -d

use redis client access

โ–ถ redis-cli -p 7088
127.0.0.1:7088> SET name lzz
(error) ERR: unknown command SET
127.0.0.1:7088> set name lzz
OK

Expected behavior

OS and Other informations
macos

Additional details

Print port number on console


name: Print port number on console
about:


Description

Kache does not print the port number after starting TCP connection
added go routine to print port number on console as well, may be unncessary but will help users

Steps to reproduce the behavior:

Expected behavior

OS and Other informations

Additional details

Reimplement RESP3 to match new interfaces

Description
Since we have switched our execution flow, it is better to move resp3 protocol to match these

Steps to reproduce the behavior:

Expected behavior

Actual Behavior

OS and Other informations

Additional details

Implement timeouts

Description
It's better if we could introduce client timeouts.

Steps to reproduce the behavior:

Expected behavior

Actual Behavior

OS and Other informations

Additional details

Key Expiration always return false

Description
Key expiration always returns false.
This leads to errors

Steps to reproduce the behavior:

Expected behavior

Actual Behavior

OS and Other informations

Additional details

Configuration files

Description
It should be able to use config files to load configuration details into the application
Preferred file format would be TOML as it's safe and can handle complex data structures

Loading Procedure

  • Parse command line arguments
  • Check if it has a --conf argument
  • If so load that provided file into memory
  • If not look for default conf file in config/default.toml path (skip when --conf presents)
  • Parse other command line arguments
  • Merge them up

When config/default.toml not presented

  • Application will try to load default values from the program

Invalid TOML file

  • When a provided .toml file was corrupted, it will immediately stop the program and panic an error

Implement Sets Data Structure

Description
Implement sets data structure

Steps to reproduce the behavior:

Expected behavior

OS and Other informations

Additional details

Revert to RESP2

Description
We need to revert back to RESP2 and use it as default until explicitly requested by a client

Steps to reproduce the behavior:

Expected behavior

Actual Behavior

OS and Other informations

Additional details

Parsing double quotation when an escape character found

Description
When parsing a string with double quotations when an escape character found program detect is as unbalanced

Steps to reproduce the behavior:

  • Start kache
  • Open netcat and try set key "val is \"something"

Expected behavior

  • Program must detect val is something as one sentence

OS and Other informations

Additional details

kache protocol draft

  • simple string
  • blob string
  • simple error
  • blob error
  • number
  • null
  • boolean
  • verbatim string
  • double
  • big number
  • array
  • map
  • set
  • push
  • attribute

Refactor connection handling

Description
Currently connection handling is a mess, it uses some func to do the job.
It will be better if we can refactor this.

Steps to reproduce the behavior:

Expected behavior

OS and Other informations

Additional details

Shall we change the name of project ?

Description
As it's initially developed as a hobby project the repo is under my gh name.

will it be better if moved this to an org under a new unique name?

Ideas are welcome

Steps to reproduce the behavior:

Expected behavior

OS and Other informations

Additional details

Make is troublesome

Description
It's obvious that many users specially windows users find it hard to develop kache because they need to install Make. It would be awesome if we can introduce mage for such build tasks

Steps to reproduce the behavior:

Expected behavior

OS and Other informations

Additional details

add kache client

  • help message
  • create a client parser which can even parse nested arrays, arrays of mixed types etc
  • connect to server(tcp)
  • read input text
  • parse input text to req command
  • send input to kache server and read resp
  • parse resp text to resp message
  • render resp from server
    • get
    • set
    • exists
    • del
    • incr
    • decr

Rename type Clients struct to something more meaningful.

Description

type Clients struct sometime becomes more confusing especially on below line.
clients.clients[client.RemoteAddr().String()] = client

Change it to something more meaningful like ClientRegistry which explains itself what it does.

Steps to reproduce the behavior:

Expected behavior

Actual Behavior

OS and Other informations

Additional details

Consider the use of defer

Description

Since this project aims to be a fast in memory database, it is better to eliminate the use of defer.
defer is nice for code readability where the Open and Close operations are close to each other and prevents to from forgetting to Close() but it has a performance penalty.

Steps to reproduce the behavior:

Expected behavior

OS and Other informations

Additional details

See: https://bytes-and-bites.com/posts/defer-go-performance/

When client is closed server entering an infinite loop

Description
When a client was closed forcibly the server start to enter an infinite loop, the reason for this was we were exiting the loop when only an EOF occurred

Steps to reproduce the behavior:

  • start kache --debug
  • start cli by using kache-cli
  • exit cli using exit

Expected behavior

  • server need to close connection

OS and Other informations

  • Windows 10

Additional details

  • PR proposed

Limit max clients

Description
we need to limit max clients per server

Steps to reproduce the behavior:

Expected behavior

Actual Behavior

OS and Other informations

Additional details

Simplify config

Description
Currently, config is loaded from config/ directory. This required to have a very good folder structure like bin/ config/

It would be better to simplify this by moving the config to root folder and keep it as conf.toml along with binary

Steps to reproduce the behavior:

Expected behavior

Actual Behavior

OS and Other informations

Additional details

Replace Mutexes with RWMutexes

Description
As submitted by a reddit user tgulacsi, Mutexes can be replaced with RWMutexes to speed up the read and writes

Need this to do in

  • Lists
  • HashMap
  • Sets

Steps to reproduce the behavior:

Expected behavior

OS and Other informations

Additional details

add golint?

  • add comment for exported function
  • don't use ALL_CAPS in Go names; use CamelCase

Improved data structures

Description
Currently, we use a map as the main backend for database. Which requires locking on manipulating keys. Map is implemented using a linked list along with buckets. This leads to a severe issue when we want to take snapshots of data and saving them to disk.

We would have to lock the map when we wanna make a snapshot

The time to duplicate a map is also high, when we have more data we need more time to copy a snapshot. We need a highly optimized data structure which gives maximum performance and minimal locking when we wanna persist data

Steps to reproduce the behavior:

Expected behavior

Actual Behavior

OS and Other informations

Additional details

Optimize the RESP3 Protocol

Description
Currently we are supporting two major protocols.

  • Resp3
  • Text Protocol(for terminals)

To work with both seamlessly we are using string arrays to represent command arguments. In resp3 we use a type conversion and store the data along with the type(directly parsed from a stream into appropriate type). This would add an overhead to the system. The reason is to execute a kache command its a must to convert whatever the Data we parsed into a string array.

So basically what we doing is type casting same data into multiple to execute a single task which is an overhead.

Proposed solution

  • Store whatever the data received from the stream as a string or a byte array
  • Store the type of the data(by prefix)
  • This would lead to less intermediate conversions
  • Convert data on demand(say we want to output an int to the client, then we convert the data into byte array and return)

Steps to reproduce the behavior:

Expected behavior

  • Same behavior

Actual Behavior

OS and Other information

Additional details

why not initialize a reader and start the for loop

func handleConnection(conn net.Conn) {
defer conn.Close()
for {
reader := protcl.NewReader(conn)
// TODO determine client type by first issued command to kache, this can improve performance
w := bufio.NewWriter(bufio.NewWriter(conn))
command, err := reader.ParseMessage()
if err != nil {

1

why not move

reader := protcl.NewReader(conn)
w := bufio.NewWriter(bufio.NewWriter(conn))

outside for loop

2

and why not just wrap with

w := bufio.NewWriter(conn)

to instead of

w := bufio.NewWriter(bufio.NewWriter(conn))

I am more confused, thank you for your answer.

Add docker image

Description
We need a docker distribution

Steps to reproduce the behavior:

Expected behavior

Actual Behavior

OS and Other informations

Additional details

kache cli not displaying version or help

Description
Kache cli not displaying help or version info

Steps to reproduce the behavior:

  • Stop kache if running
  • Start CLI with kache-cli version
  • CLI will dump a tcp dial timeout

Expected behavior

  • to display version info or help

OS and Other informations

  • Windows 10

Additional details

set.Intersection incorrect

Description

set.Intersection returns incorrect data

Steps to reproduce the behavior:

set1 := set.New()
set2 := set.New()
set3 := set.New()

set1.Add([]string{"a", "b", "c", "d"})
set2.Add([]string{"b"})
set3.Add([]string{"a", "b"})

inter := set.Intersection([]set.Set{*set1, *set2, *set3})
	
fmt.Println(inter)

prints [a a b b]

Expected behavior

prints [b]

OS and Other informations

Additional details

Updated Slack Join channel

Description
The link to join slack did not work. I updated the link but here its as a reminder

join slack

Steps to reproduce the behavior:

Expected behavior

OS and Other informations

Additional details

Telnet clients broken

Description
After merge of #84 the telnet client does not work anymore

Steps to reproduce the behavior:

  • open telnet and connect to kache
  • issue a command

Expected behavior

  • reply from kache in correct format

Actual Behavior

  • command is not parsed anymore

OS and Other informations

Additional details

Key eviction

Description
Keys should expire when they have set flags

  • Create basic expiration
  • Optimize basic expiration strategy
  • Implement passive cleaning

Caching redis itself ?

You can then cache redis itself and so take the load of redis ?
Seems like this is why this was made ?

Move things out

Description
We are currently keeping our codebase inside the internal package. It would be awesome if we could move it out so we can use the application as a library

Steps to reproduce the behavior:

Expected behavior

Actual Behavior

OS and Other informations

Additional details

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.