Socket
Socket
Sign inDemoInstall

github.com/PuerkitoBio/redisc

Package Overview
Dependencies
2
Alerts
File Explorer

Install Socket

Detect and block malicious and high-risk dependencies

Install

    github.com/PuerkitoBio/redisc

Package redisc implements a redis cluster client on top of the redigo client package. It supports all commands that can be executed on a redis cluster, including pub-sub, scripts and read-only connections to read data from replicas. See http://redis.io/topics/cluster-spec for details. The package defines two main types: Cluster and Conn. Both are described in more details below, but the Cluster manages the mapping of keys (or more exactly, hash slots computed from keys) to a group of nodes that form a redis cluster, and a Conn manages a connection to this cluster. The package is designed such that for simple uses, or when keys have been carefully named to play well with a redis cluster, a Cluster value can be used as a drop-in replacement for a redis.Pool from the redigo package. Similarly, the Conn type implements redigo's redis.Conn interface (and the augmented redis.ConnWithTimeout one too), so the API to execute commands is the same - in fact the redisc package uses the redigo package as its only third-party dependency. When more control is needed, the package offers some extra behaviour specific to working with a redis cluster: Slot and SplitBySlot functions to compute the slot for a given key and to split a list of keys into groups of keys from the same slot, so that each group can safely be handled using the same connection. *Conn.Bind (or the BindConn package-level helper function) to explicitly specify the keys that will be used with the connection so that the right node is selected, instead of relying on the automatic detection based on the first parameter of the command. *Conn.ReadOnly (or the ReadOnlyConn package-level helper function) to mark a connection as read-only, allowing commands to be served by a replica instead of the master. RetryConn to wrap a connection into one that automatically follows redirections when the cluster moves slots around. Helper functions to deal with cluster-specific errors. The Cluster type manages a redis cluster and offers an interface compatible with redigo's redis.Pool: Along with some additional methods specific to a cluster: If the CreatePool function field is set, then a redis.Pool is created to manage connections to each of the cluster's nodes. A call to Get returns a connection from that pool. The Dial method, on the other hand, guarantees that the returned connection will not be managed by a pool, even if CreatePool is set. It calls redigo's redis.Dial function to create the unpooled connection, passing along any DialOptions set on the cluster. If the cluster's CreatePool field is nil, Get behaves the same as Dial. The Refresh method refreshes the cluster's internal mapping of hash slots to nodes. It should typically be called only once, after the cluster is created and before it is used, so that the first connections already benefit from smart routing. It is automatically kept up-to-date based on the redis MOVED responses afterwards. A cluster must be closed once it is no longer used to release its resources. The connection returned from Get or Dial is a redigo redis.Conn interface (that also implements redis.ConnWithTimeout), with a concrete type of *Conn. In addition to the interface's required methods, *Conn adds the following methods: The returned connection is not yet connected to any node; it is "bound" to a specific node only when a call to Do, Send, Receive or Bind is made. For Do, Send and Receive, the node selection is implicit, it uses the first parameter of the command, and computes the hash slot assuming that first parameter is a key. It then binds the connection to the node corresponding to that slot. If there are no parameters for the command, or if there is no command (e.g. in a call to Receive), a random node is selected. Bind is explicit, it gives control to the caller over which node to select by specifying a list of keys that the caller wishes to handle with the connection. All keys must belong to the same slot, and the connection must not already be bound to a node, otherwise an error is returned. On success, the connection is bound to the node holding the slot of the specified key(s). Because the connection is returned as a redis.Conn interface, a type assertion must be used to access the underlying *Conn and to be able to call Bind: The BindConn package-level function is provided as a helper for this common use-case. The ReadOnly method marks the connection as read-only, meaning that it will attempt to connect to a replica instead of the master node for its slot. Once bound to a node, the READONLY redis command is sent automatically, so it doesn't have to be sent explicitly before use. ReadOnly must be called before the connection is bound to a node, otherwise an error is returned. For the same reason as for Bind, a type assertion must be used to call ReadOnly on a *Conn, so a package-level helper function is also provided, ReadOnlyConn. There is no ReadWrite method, because it can be sent as a normal redis command and will essentially end that connection (all commands will now return MOVED errors). If the connection was wrapped in a RetryConn call, then it will automatically follow the redirection to the master node (see the Redirections section). The connection must be closed after use, to release the underlying resources. The redis cluster may return MOVED and ASK errors when the node that received the command doesn't currently hold the slot corresponding to the key. The package cannot reliably handle those redirections automatically because the redirection error may be returned for a pipeline of commands, some of which may have succeeded. However, a connection can be wrapped by a call to RetryConn, which returns a redis.Conn interface where only calls to Do, Close and Err can succeed. That means pipelining is not supported, and only a single command can be executed at a time, but it will automatically handle MOVED and ASK replies, as well as TRYAGAIN errors. Note that even if RetryConn is not used, the cluster always updates its mapping of slots to nodes automatically by keeping track of MOVED replies. The concurrency model is similar to that of the redigo package: Cluster methods are safe to call concurrently (like redis.Pool). Connections do not support concurrent calls to write methods (Send, Flush) or concurrent calls to the read method (Receive). Connections do allow a concurrent reader and writer. Because the Do method combines the functionality of Send, Flush and Receive, it cannot be called concurrently with other methods. The Bind and ReadOnly methods are safe to call concurrently, but there is not much point in doing so for as both will fail if the connection is already bound. Create and use a cluster.


Version published

Readme

Source

Go Reference Build Status

redisc

Package redisc implements a redis cluster client built on top of the redigo package. See the documentation for details.

Installation

$ go get [-u] [-t] github.com/mna/redisc

Releases

  • v1.4.0 : Improve the reliability of the refresh of cluster mapping for edge cases where no nodes are known anymore (thanks to @ljfuyuan).

  • v1.3.2 : Export the HashSlots constant to make it nicer to write the Cluster.LayoutRefresh function signature.

  • v1.3.1 : Fix closing/releasing of connections used in Cluster.EachNode.

  • v1.3.0 : Add Cluster.EachNode to call a function with a connection for each known node in the cluster (e.g. to run diagnostics commands on each node or to collect all keys in a cluster); add optional Cluster function field BgError to receive notification of errors happening in background topology refreshes and on closing of RetryConn after following a redirection to a new connection; add optional Cluster function field LayoutRefresh to receive the old and new cluster slot mappings to server address(es); prevent unnecessary cluster layout refreshes when the internal mapping is the same as the redirection error; better handling of closed Cluster; move CI to Github Actions; drop support for old Go versions (currently tested on 1.15+); enable more static analysis/linters; refactor tests to create less separate clusters and run faster.

  • v1.2.0 : Use Go modules, fix a failing test due to changed error message on Redis 6.

  • v1.1.7 : Do not bind to a random node if Do is called without a command and the connection is not already bound (thanks to @tysonmote).

  • v1.1.6 : Append the actual error messages when a refresh returns "all nodes failed" error.

  • v1.1.5 : Add Cluster.PoolWaitTime to configure the time to wait on a connection from a pool with MaxActive > 0 and Wait set to true (thanks to @iwanbk).

  • v1.1.4 : Add Conn.DoWithTimeout and Conn.ReceiveWithTimeout to match redigo's ConnWithTimeout interface (thanks to @letsfire).

  • v1.1.3 : Fix handling of ASK replies in RetryConn.

  • v1.1.2 : Remove mention that StartupNodes in Cluster struct needs to be master nodes (it can be replicas). Add supporting test.

  • v1.1.1 : Fix CI tests.

  • v1.1.0 : This release builds with the github.com/gomodule/redigo package (the new import path of redigo, which also has a breaking change in its v2.0.0, the PMessage type has been removed and consolidated into Message).

  • v1.0.0 : This release builds with the github.com/garyburd/redigo package, which - according to its readme - will not be maintained anymore, having moved to github.com/gomodule/redigo for future development. As such, redisc will not be updated with the old redigo package, this version was created only to avoid causing issues to users of redisc.

Documentation

The code documentation is the canonical source for documentation.

The design goal of redisc is to be as compatible as possible with the redigo package. As such, the Cluster type can be used as a drop-in replacement to a redis.Pool when moving from a standalone Redis to a Redis Cluster setup, and the connections returned by the cluster implement redigo's redis.Conn interface. The package offers additional features specific to dealing with a cluster that may be needed for more advanced scenarios.

The main features are:

  • Drop-in replacement for redis.Pool (the Cluster type implements the same Get and Close method signatures).
  • Connections are redis.Conn interfaces and use the redigo package to execute commands, redisc only handles the cluster part.
  • Support for all cluster-supported commands including scripting, transactions and pub-sub (within the limitations imposed by Redis Cluster).
  • Support for READONLY/READWRITE commands to allow reading data from replicas.
  • Client-side smart routing, automatically keeps track of which node holds which key slots.
  • Automatic retry of MOVED, ASK and TRYAGAIN errors when desired, via RetryConn.
  • Manual handling of redirections and retries when desired, via IsTryAgain and ParseRedir.
  • Automatic detection of the node to call based on the command's first parameter (assumed to be the key).
  • Explicit selection of the node to call via BindConn when needed.
  • Support for optimal batch calls via SplitBySlot.

Note that to make efficient use of Redis Cluster, some upfront work is usually required. A good understanding of Redis Cluster is highly recommended and the official Redis website has good documentation that covers this. In particular, Migrating to Redis Cluster will help understand how straightforward (or not) the migration may be for your specific case.

Alternatives

Support

There are a number of ways you can support the project:

  • Use it, star it, build something with it, spread the word!
  • Raise issues to improve the project (note: doc typos and clarifications are issues too!)
    • Please search existing issues before opening a new one - it may have already been adressed.
  • Pull requests: please discuss new code in an issue first, unless the fix is really trivial.
    • Make sure new code is tested.
    • Be mindful of existing code - PRs that break existing code have a high probability of being declined, unless it fixes a serious issue.
  • Sponsor the developer
    • See the Github Sponsor button at the top of the repo on github

License

The BSD 3-Clause license.

FAQs

Last updated on 20 Oct 2023

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc