mirror of
https://git.mills.io/kayos/bitraft.git
synced 2024-06-28 09:41:38 +00:00
added ECHO command
This commit is contained in:
parent
150fa41432
commit
a2f99d9599
28
README.md
28
README.md
@ -1,10 +1,11 @@
|
|||||||
# kvnode
|
# kvnode
|
||||||
|
|
||||||
Very simple key value store.
|
Minimal Key/Value store with basic Redis support.
|
||||||
|
|
||||||
- Redis API
|
- Redis API
|
||||||
- LevelDB storage
|
- LevelDB disk-based storage
|
||||||
- Raft support with [Finn](https://github.com/tidwall/finn) commands.
|
- Raft support with [Finn](https://github.com/tidwall/finn) commands
|
||||||
|
- Compatible with existing Redis clients
|
||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
|
|
||||||
@ -20,6 +21,25 @@ FLUSHDB
|
|||||||
SHUTDOWN
|
SHUTDOWN
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Key scanning
|
||||||
|
|
||||||
|
The `KEYS` command returns data in order of the key.
|
||||||
|
The `PIVOT` keyword allows for efficient paging.
|
||||||
|
For example:
|
||||||
|
```
|
||||||
|
redis> MSET key1 1 key2 2 key3 3 key4 4
|
||||||
|
OK
|
||||||
|
redis> KEYS * LIMIT 2
|
||||||
|
1) "key1"
|
||||||
|
2) "key2"
|
||||||
|
redis> KEYS * PIVOT key2 LIMIT 2
|
||||||
|
1) "key3"
|
||||||
|
2) "key4"
|
||||||
|
```
|
||||||
|
|
||||||
|
The `PDEL` commands will delete all items matching the specified pattern.
|
||||||
|
|
||||||
|
|
||||||
## Backup and Restore
|
## Backup and Restore
|
||||||
|
|
||||||
To backup data:
|
To backup data:
|
||||||
@ -40,7 +60,7 @@ To restore:
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```
|
||||||
kvnode-server --parse-snapshot state.bin | redis-cli -h 10.0.1.5 -p 4920
|
kvnode-server --parse-snapshot state.bin | redis-cli -h 10.0.1.5 -p 4920 --pipe
|
||||||
```
|
```
|
||||||
|
|
||||||
This will execute all of the `state.bin` commands on the leader at `10.0.1.5:4920`
|
This will execute all of the `state.bin` commands on the leader at `10.0.1.5:4920`
|
||||||
|
15
server.go
15
server.go
@ -111,7 +111,10 @@ func (kvm *Machine) Command(
|
|||||||
) (interface{}, error) {
|
) (interface{}, error) {
|
||||||
switch strings.ToLower(string(cmd.Args[0])) {
|
switch strings.ToLower(string(cmd.Args[0])) {
|
||||||
default:
|
default:
|
||||||
|
log.Warningf("unknown command: %s\n", cmd.Args[0])
|
||||||
return nil, finn.ErrUnknownCommand
|
return nil, finn.ErrUnknownCommand
|
||||||
|
case "echo":
|
||||||
|
return kvm.cmdEcho(m, conn, cmd)
|
||||||
case "set":
|
case "set":
|
||||||
return kvm.cmdSet(m, conn, cmd)
|
return kvm.cmdSet(m, conn, cmd)
|
||||||
case "mset":
|
case "mset":
|
||||||
@ -235,6 +238,11 @@ func WriteRedisCommandsFromSnapshot(wr io.Writer, snapshotPath string) error {
|
|||||||
if _, err := io.ReadFull(r, value); err != nil {
|
if _, err := io.ReadFull(r, value); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if len(key) == 0 || key[0] != 'k' {
|
||||||
|
// do not accept keys that do not start with 'k'
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
key = key[1:]
|
||||||
cmd = cmd[:0]
|
cmd = cmd[:0]
|
||||||
cmd = append(cmd, "*3\r\n$3\r\nSET\r\n$"...)
|
cmd = append(cmd, "*3\r\n$3\r\nSET\r\n$"...)
|
||||||
cmd = strconv.AppendInt(cmd, int64(len(key)), 10)
|
cmd = strconv.AppendInt(cmd, int64(len(key)), 10)
|
||||||
@ -330,6 +338,13 @@ func (kvm *Machine) cmdMset(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (kvm *Machine) cmdEcho(m finn.Applier, conn redcon.Conn, cmd redcon.Command) (interface{}, error) {
|
||||||
|
if len(cmd.Args) != 2 {
|
||||||
|
return nil, finn.ErrWrongNumberOfArguments
|
||||||
|
}
|
||||||
|
conn.WriteBulk(cmd.Args[1])
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
func (kvm *Machine) cmdGet(m finn.Applier, conn redcon.Conn, cmd redcon.Command) (interface{}, error) {
|
func (kvm *Machine) cmdGet(m finn.Applier, conn redcon.Conn, cmd redcon.Command) (interface{}, error) {
|
||||||
if len(cmd.Args) != 2 {
|
if len(cmd.Args) != 2 {
|
||||||
return nil, finn.ErrWrongNumberOfArguments
|
return nil, finn.ErrWrongNumberOfArguments
|
||||||
|
Loading…
Reference in New Issue
Block a user