Giter Club home page Giter Club logo

valkey-io / valkey-glide Goto Github PK

View Code? Open in Web Editor NEW
198.0 10.0 42.0 236.28 MB

An open source Valkey client library that supports Valkey and Redis open source 6.2, 7.0 and 7.2. Valkey GLIDE is designed for reliability, optimized performance, and high-availability, for Valkey and Redis OSS based applications. GLIDE is a multi language client library, written in Rust with programming language bindings, such as Java and Python

License: Apache License 2.0

Rust 7.02% Shell 0.14% Python 19.22% JavaScript 0.22% C# 0.53% TypeScript 19.51% Java 52.43% Makefile 0.03% Go 0.89%

valkey-glide's Introduction

Valkey GLIDE

Valkey General Language Independent Driver for the Enterprise (GLIDE), is an open-source Valkey client library. Valkey GLIDE is one of the official client libraries for Valkey, and it supports all Valkey commands. Valkey GLIDE supports Valkey 7.2 and above, and Redis open-source 6.2, 7.0 and 7.2. Application programmers use Valkey GLIDE to safely and reliably connect their applications to Valkey- and Redis OSS- compatible services. Valkey GLIDE is designed for reliability, optimized performance, and high-availability, for Valkey and Redis OSS based applications. It is sponsored and supported by AWS, and is pre-configured with best practices learned from over a decade of operating Redis OSS-compatible services used by hundreds of thousands of customers. To help ensure consistency in application development and operations, Valkey GLIDE is implemented using a core driver framework, written in Rust, with language specific extensions. This design ensures consistency in features across languages and reduces overall complexity.

Supported Engine Versions

Valkey GLIDE is API-compatible with the following engine versions:

Engine Type 6.2 7.0 7.2
Valkey - - V
Redis V V V

Current Status

In this release, Valkey GLIDE is available for Python and Java. Support for Node.js is actively under development, with plans to include more programming languages in the future. We're tracking future features on the roadmap.

Getting Started

Getting Help

If you have any questions, feature requests, encounter issues, or need assistance with this project, please don't hesitate to open a GitHub issue. Our community and contributors are here to help you. Before creating an issue, we recommend checking the existing issues to see if your question or problem has already been addressed. If not, feel free to create a new issue, and we'll do our best to assist you. Please provide as much detail as possible in your issue description, including:

  1. A clear and concise title
  2. Detailed description of the problem or question
  3. Reproducible test case or step-by-step instructions
  4. Valkey GLIDE version in use
  5. Operating system details
  6. Server version
  7. Cluster or standalone setup information, including topology, number of shards, number of replicas, and data types used
  8. Relevant modifications you've made
  9. Any unusual aspects of your environment or deployment
  10. Log files

Contributing

GitHub is a platform for collaborative coding. If you're interested in writing code, we encourage you to contribute by submitting pull requests from forked copies of this repository. Additionally, please consider creating GitHub issues for reporting bugs and suggesting new features. Feel free to comment on issues that interest. For more info see Contributing.

License

valkey-glide's People

Contributors

shachlanamazon avatar barshaul avatar shohamazon avatar yury-fridlyand avatar aaron-congo avatar acarbonetto avatar cyip10 avatar sanhalacogluimproving avatar nihohit avatar avifenesh avatar tjzhang-bq avatar ikolomi avatar yipin-chen avatar jonathanl-bq avatar alon-arenberg avatar gumpacg avatar asafpamzn avatar gilboaaws avatar eifrah-aws avatar adarovadya avatar jduo avatar talxsha avatar alexander-shabanov avatar asheryerm avatar yulazariy avatar alexey-temnikov avatar elen-ghulam avatar adanwattad avatar sa1gur avatar jamesx-improving avatar

Stargazers

smartroaddev avatar Clayton Kehoe avatar  avatar Felipe Kellermann avatar  avatar Aaron Roh avatar Radoslav Nemeth avatar Kevin McGehee avatar  avatar Pierre avatar Chi Nguyen avatar Victor Andres Alfonzo avatar xingbowang avatar Guillaume Koenig avatar Amit Nagler avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar Tom F avatar Hindy avatar  avatar Oleh avatar Calvin avatar Jonathan Bluett-Duncan avatar  avatar Masayuki Morita avatar  avatar sawasa avatar Basile Deustua avatar Ross Heo avatar  avatar Lihu Wu avatar Time avatar WonChul Heo avatar Charles Sieg avatar Ponzmild avatar bion howard avatar  avatar Filipe Oliveira (Personal) avatar James Ward avatar Padraic Renaghan avatar Josh Oberwetter avatar  avatar Nacho Rovirosa avatar Anne Thorpe avatar Shivendu Amale avatar Gianluca Esposito avatar Paul Tuckey avatar Zixuan Tan avatar Sergey Kovalev avatar Pratik Dey avatar  avatar Taketoday avatar Rajan Ponnappan avatar Xiaofan Hu avatar RichardLee avatar yzhengwei avatar  avatar  avatar  avatar MAD CITY MULTIMEDIA avatar Travis Smith avatar Carlos Cima avatar James O'Cull avatar Yoni Revah avatar Krittin Khanueng avatar Ping Xie avatar Basel J. Hamadeh avatar Seonu Jang avatar Fco. Javier Clavero Álvarez avatar Samuel Colvin avatar  avatar Tihomir Krasimirov Mateev avatar Roman Gershman avatar Ravi Gupta avatar Samrose avatar Kotaro Inoue avatar Marchandise Rudy avatar Y.Fujiwara avatar Jerry Yang avatar Altan Ozlu avatar Borko avatar Chris "Not So" Short avatar  avatar  avatar Yohei Yamamoto avatar Ian Stapleton Cordasco avatar Zion Amsalem avatar Ankur Bulsara avatar  avatar Ruslan Konviser avatar Andrea Bongiorno avatar Neos21 avatar Nelson Correia avatar Shoham avatar

Watchers

 avatar  avatar  avatar  avatar Qu Chen avatar  avatar Yaron Sananes avatar  avatar Brandon Janson avatar  avatar

valkey-glide's Issues

Add language version matrices to CI

We should test our clients on a wide range of language and redis server versions, instead of on a single one.
This should be done once we have more minutes for our Github actions - ATM we have precious few.

Analyze Rustls on C# results

We've seen that when running 1000 concurrent tasks with 100 bytes, rustls harms performance significantly. we should investigate the reason for this.

Use rust library for DNS resolution

We can consider to use https://docs.rs/trust-dns-resolver/latest/trust_dns_resolver/ which can get the host system config. I will add an item to our new shiny backlog.
/etc/resolv.conf
https://docs.rs/trust-dns-resolver/latest/trust_dns_resolver/#using-the-host-system-config

docs.rsdocs.rs
trust_dns_resolver - Rust
The Resolver is responsible for performing recursive queries to lookup domain names.

docs.rsdocs.rs
trust_dns_resolver - Rust
The Resolver is responsible for performing recursive queries to lookup domain names.

Appsec

[X] 1. Provide supporting materials for Design Review
[X] 2. Provide Project Resources
[X] 3. Provide supporting material for Threat Model Review
[] 4. Review supporting material with your Security Guardian
[] 4a. Have your Guardian post their notes to the ticket correspondence
[] 5. Complete the AppSec Review Process Training
[] 6. Complete the Pentest Questionnaire
[] 7. Change ticket Status to Assigned once Items 1-6 are completed

Timeouts

  • Connection timeout standalone
  • Connection timeout cluster
  • Command timeout
  • standalone Heartbeat
  • cluster Heartbeat

The client is composed of multiple layers, each operating asynchronously from the others:

  • Wrapper (in JS/Python/ etc.) →
  • core API →
  • core client →
  • core connection →
  • MPSC channel (in order to allow multiplexing) →
  • parser ->
  • TCP stream →
  • server.

Responses are communicated back, in the inverse order.
We need to define what’s the meaning of connection & response timeouts - what should the user expect these values to mean. We assume that the user expects that the timeouts represent the amount of time they are willing to wait for success on the external-most layers - the wrapper. So a timeout represents the amount of time to wait for a request / connection attempt to pass from the wrapper to the server, and the response to pass through all layers back to the wrapper.
We will also set an internal timeout, so that messages that are sent to a hanging server will cause the core client to timeout, just so that the core’s state will match the wrapper’s state.
We won’t retry operations, unless we receive EAGAIN errors from the TCP connection, or MOVED, ASK, CLUSTERDOWN, LOADING or TRYAGAIN errors from a cluster node.

defaults: connection timeout 250ms, response timeout 250 ms. TCP keepalive - TBD.

reconnection

There are two types of reconnection: during client creation and in steady state. As a client is being created, we will try to establish a connection with a timeout that will be exposed to the user. That timeout will encompass the whole connection process, including multiple retries with exponential backoff between them. During the initialize phase, we shall raise an exception only if a fatal error occurs, for example: standalone endpoint given to cluster client, all seed nodes are unreachable. However, if the client is partially functional, e.g.: we can get the cluster topology from at least one of the seed nodes or we can connect only to the primary in standalone, we shall allow the user to use this client and we shall work on establishing all connections / refreshing the cluster topology asynchronously on a background job on the core side. When the client is in steady-state, reconnecting will always be handled by the background job and be transparent to the user. The backoff configurations for the steady-state reconnection will be set internally and won’t be configurable by the user.

The background job is supposed to act as a connection watchdog and do the following:

  1. Monitor the connections' health
  2. If a connection is broken, keep trying to reconnect until the connection is established using exponential backoff and jitter (e.g. - without limiting the number of retries, as long as the client is alive).

If a user tries to execute a command and the client doesn’t have a ready connection at that time, a connection error will be raised to the user.

Timeouts will not trigger reconnection attempts, since they might represent a busy server that is still available, and reconnection will only increase the load on the server. We will try to reconnect if the connection is broken on sent messages, but we will need to understand how and to which value to set this timeout.

defaults: exponential backoff - unlimited retries, time between retries: uniform distribution up to 100ms * 2^current retry. Initial connection timeout - TBD.

Full commands support

Node:

  • bitmap
  • cluster management
  • connection management
  • generic
  • geo
  • hash
  • hyperloglog
  • list
  • scripting
  • server management
  • set
  • sorted set
  • stream
  • string
  • transactions
  • pub / sub

Python:

  • bitmap
  • cluster management
  • connection management
  • generic
  • geo
  • hash
  • hyperloglog
  • list
  • scripting
  • server management
  • set
  • sorted set
  • stream
  • string
  • transactions
  • pub / sub

Add cargo-udeps to CI

The last time it was tested, cargo-udeps failed to handle dev-dependencies correctly. Once this is fixed, we should integrate it into our CI.

Full commands support

MVP commands support (150) - 90 commands left, not including STREAM, PUBSUB, LUA.

Loading error

retry command when receiving loafing error from replica

Cluster client: execute_on_all_nodes doesn't handle cluster errors and retries

https://github.com/redis-rs/redis-rs/pull/842/files#diff-3081b035ea7b3a6c6fbf36bdcc857b7d1405e36fbe98df550dc7ba187275a638

If we execute a command to all nodes/primaries in this function, we're not handling CME errors (e.g. MOVED, ASK..) nor refreshing topology.
I think we should have a wrapper function that decide which nodes to send the command to, and an inner function with the logic of executing the request.
e.g.

fn request (...) {
  nodes = get_nodes_to_be_executed()
  for node in nodes:
     node.execute_request()
}

fn execute_request(...) {
        loop {
            // Get target address and response.
            let (addr, rv) = {
   ...
                (addr, func(conn))
            };
            match rv {
                Ok(rv) => return Ok(rv),
                Err(err) => {
       ...
                    }
}
}

Add cargo-outdated to CI

The last time I tested this, it gave erroneous results on the python library. It should be re-examined after a couple of versions.

logger-core - calling `init_console` twice disables logging

The same might be true of init_file.

sample tests -

#[cfg(test)]
mod tests {
    use crate::{init_console, init_file, log_trace, FILE_DIRECTORY};
    use rand::{distributions::Alphanumeric, Rng};
    use std::{
        fs::{read_dir, read_to_string},
        io,
    };

    fn generate_random_string(length: usize) -> String {
        rand::thread_rng()
            .sample_iter(&Alphanumeric)
            .take(length)
            .map(char::from)
            .collect()
    }

    fn get_file_contents(file_name: &str) -> String {
        let files = read_dir(FILE_DIRECTORY).unwrap();
        let file = files
            .into_iter()
            .find(|path| {
                path.as_ref()
                    .unwrap()
                    .path()
                    .file_name()
                    .unwrap()
                    .to_str()
                    .unwrap()
                    .starts_with(file_name)
            })
            .unwrap();
        read_to_string(file.unwrap().path()).unwrap()
    }

    #[test]
    fn log_to_file_works_after_multiple_inits() {
        let identifier = generate_random_string(10);
        init_file(crate::Level::Trace, identifier.as_str());
        init_file(crate::Level::Trace, identifier.as_str());
        log_trace(identifier.clone(), "foo");

        let contents = get_file_contents(identifier.as_str());

        assert!(
            contents.contains(identifier.as_str()),
            "Contens: {}",
            contents
        );
        assert!(contents.contains("foo"), "Contens: {}", contents);
    }

    #[test]
    fn log_to_console_works_after_multiple_inits() {
        let identifier = generate_random_string(10);

        init_console(crate::Level::Trace);
        init_console(crate::Level::Trace);
        log_trace(identifier.clone(), "foo");

        // let mut stdout = io::stdout().lock();
        // let lines = stdout.lines();

        // let contents = get_file_contents(identifier.as_str());

        // assert!(
        //     contents.contains(identifier.as_str()),
        //     "Contens: {}",
        //     contents
        // );
        // assert!(contents.contains("foo"), "Contens: {}", contents);
    }

    #[test]
    fn log_to_console_works_after_file_init() {}

    #[test]
    fn log_to_file_works_after_console_init() {
        let identifier = generate_random_string(10);
        init_console(crate::Level::Trace);
        init_file(crate::Level::Trace, identifier.as_str());
        log_trace(identifier.clone(), "foo");

        let contents = get_file_contents(identifier.as_str());

        assert!(
            contents.contains(identifier.as_str()),
            "Contens: {}",
            contents
        );
        assert!(contents.contains("foo"), "Contens: {}", contents);
    }
}

Add a shutdown hook to ensure that the socket file is deleted

If the application threads are calling exit() it can shutdown the socket listener thread without cleaning the socket file.
If we'll go with the socket approach, we need to consider some kind of shutdown hooks/ use at_exit to ensure we delete the socket file when the process is closed.

PubSub support

PubSub support.
We will support only RESP3. For the push notification.
RESP3 and pubsub in redis-rs currently in progress.

How to handle disconnections? both in standalone and CME.

  • Core rust, support pub sub in cluster.
  • maintain subscription state after disconnect
  • Add to the socket manager option to push out of band messages
  • Python
  • node

Things to add to benchmarks

  • values - random strings instead of recurring 0's. The strings should be recomputed before each usage instead of reused.
  • Write JSON results to file. Receive file name as a command-line argument.
  • Write a program that receives names of all JSON result files in a run, and collects them into a CSV file
  • Clear the DB before each benchmark, in order to ensure that past benchmarks don't affect our results.
  • Take address + port as an optional command-line argument, to allow benchmarking against remote server.
  • (consider) Take optional parameter to disable non-babushka benchmarks, if we only want to measure a change's improved perf.

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.