Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Design review on redis/rediscluster store

Abierto
#116 9 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
18/100
Tipo de issue
Nueva funcionalidad
Claridad
Necesita aclaración
Estado de actividad
Estancado
Stack tecnológico
go, redis

Línea de trabajo

Start with the original feature requirements in issue #9 and the store interface in store/store.go. Review the proposed Redis operations for List, DeleteTree, locking, watching, and atomic methods, then clarify which behaviors and atomicity guarantees are required. Done means an agreed design and concrete scope for the Redis/RedisCluster store; this issue does not yet define an implementation task.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

kind/feature kind/proposal store/meta

This is a following up discussion on the design review of redis driver.
the original feature requirements are discussed here: https://github.com/docker/libkv/issues/9
For store interface, please refer to here: https://github.com/docker/libkv/blob/master/store/store.go#L63

Redis is an in-memory key/value storage, a single thread server which supports rich data structures and lua script. It also can grant ttl(time-to-live) for each key and evict the expired keys automatically. This feature enables us to impl such functions straightforward.

Put(key string, value []byte, options *WriteOptions) error
Get(key string) (*KVPair, error)
Delete(key string) error
Exists(key string) (bool, error)

Redis also provided a scan feature which lookups all keyspace with a pattern given. It can be used to impl List and DeleteTree methods with the following file hierarchy:

set /foo bar
set /dir1/foo bar
set /dir1/dir2/foo bar

so if we call List("/"), we need to scan all keyspace and return those keys matched "/".
if we call List("/dir1/dir2"), we need to use pattern "/dir1/dir2/
" instead.
In this case, DeleteTree will be performed in two steps: 1. list the tree 2. batch delete all keys in the tree.
But that really depends how atomic we want here. If we need this operation atomaitcally, we need to move these two functions into a lua script (which will be discussed later)

For Lock implementation, redis did provide such features called "set if not exist" and "set if exist" http://redis.io/commands/set
so the one who create the key owns the lock. Release the lock actually means delete the key.
The impl can be trivial as well (for handling ttl, we just need a goroutine to refresh it's expiration time through calling set)

redisclient.Do("set", $key, $value, "NX", "EX", $ttl_in_second)
// once we hold the key, we can have a dedlicated goroutine to handle ttl
ticker := time.NewTick( ttl / 3)
for range ticker.T {
    redisclient.Do("set", $key, $value, "XX", "EX", $ttl_in_second) // update ttl only when key exist.
}

Watch API basically allows client to receive events regarding to the changes of a key (or a directory). In redis, we can borrow a keyspace notification feature(http://redis.io/topics/notifications). Since keyspace notification will deliver any events of the whole entire keyspace, client need to filter out thoese irrelevants.

func (r *Redis) WatchXXX(key string, stopCh <-chan struct{}) (<-chan *KVPair, error){
    psc := redislib.PubSubConn{client: r.client}
    psc.PSubscribe("__keyevent*__:*") // doing a pattern subscribe for all keyevent notification
    respChan :=make(chan *KVPair)
    go func(){
        for {
            // watch stopChan
            select{
                case <-stopCh:
                    // doing unsubscribe and close respChan..
                default:
            }
            switch n := psc.Receive().(type) {
                    case redis.PMessage:
                        // filter the key part and enque to respChan if found any of interest

            }
        }
    }()
    return respChan, nil
}

Script allows multiple non-blocking commands to be run without being interrupted by any coming client requests.
Here is a simple script example from stackoverflow
So that is really useful to impl DeleteTree, AtomicPut and AtomicDelete.

Feel free to modify this issue and please let me know how you think about this. thanks

Lenguaje dominante
Go
Estrellas
847
Forks
204
Métricas de merge de PR
Sin PR fusionados en 30 d

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de docker/libkv

Todos los issues de docker/libkv

Issues similares

Más issues de Go

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.