DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Redis-Based Tomcat Session Management
  • Enhancing Performance With Amazon Elasticache Redis: In-Depth Insights Into Cluster and Non-Cluster Modes
  • Scaling Databases With EclipseLink And Redis
  • Automatic Code Transformation With OpenRewrite

Trending

  • Streamlining Event Data in Event-Driven Ansible
  • Beyond Linguistics: Real-Time Domain Event Mapping with WebSocket and Spring Boot
  • AI, ML, and Data Science: Shaping the Future of Automation
  • Agile and Quality Engineering: A Holistic Perspective
  1. DZone
  2. Software Design and Architecture
  3. Microservices
  4. Redis Clustering Best Practices With Keys

Redis Clustering Best Practices With Keys

See Redis clustering best practices.

By 
Kyle Davis user avatar
Kyle Davis
·
Jun. 18, 19 · Opinion
Likes (1)
Comment
Save
Tweet
Share
16.7K Views

Join the DZone community and get the full member experience.

Join For Free

What is a key anyway in Redis? The original intention of Redis (or any key-value store) was to have a particular key, or identifier, for each individual piece of data. Redis quickly stretched this concept with data types, where a single key could refer to multiple (even millions of) pieces of data. As modules came to the ecosystem, the idea of a key was stretched even further because a single piece of data could now span multiple keys (for a RediSearch index, as an example). So, when asked if Redis is a key-value store, I usually respond with "it descends from the key-value line of databases" but note that, at this point, it's hard to justify Redis as a key-value store alone.

Image title

One place, however, where keys in Redis are still vitally important is clustering. In Redis, data resides in one place in a cluster, and each node or shard has a portion of the . Of course, when running with high availability, your data may reside in a replica, but at no point is a single key split among multiple nodes.

A cluster is divided up among 16,384 slots - the maximum number of nodes or shards in a Redis cluster (if you have that many, get in touch with us!). Since most clusters consist of a much smaller number of nodes, these hash slots are logical divisions of the keys. In an oversimplified example of a 4-node cluster, we'd have the following layout:

Image title

Note: In Redis Enterprise, there is a further division into shards on each node. It is done the same way, but instead of nodes it's divided into shards.

As an example, if you have a key that you know is in slot 2,000, then you know the data resides on Node #0. If the key is in slot 9,000, then it's on Node #2. In reality, it's much more complex than this (with slots moving and rebalancing all the time), but for the purposes of understanding transactions and keys, this simplified conceptual understanding of clustering will do.

So how are keys related to slots? These slots are actually hash slots, in which each key is put through a hashing function to mathematically derive a single number from a string of characters of any length. Hashing enters public conversations most often when it comes to password hashing, which is a related but much more complex calculation. In the same way, your password is not directly stored, but rather a mathematical representation of that password, the key you request actually boils down to its mathematical representation (in this case with the CRC16 hashing function). CRC16 will return a 14-bit number we can then modulo by 16384. Interesting coincidence that this is the number of hash slots available, no?

How Does This All Relate to Transactions in Redis?

Transactions in Redis only occur within the same hash slot, which ensures the highest throughput. Since there is no inter-node/shard communication is needed, many failures scenarios are eliminated. Given this, you have to be sure that when you go out to do a transaction, all the keys involved are on the same slot. So, how do you if your key is on the same slot (and the same node/shard) as another key in a transaction?

While it is possible for many keys to be in the same hash slot, this is unpredictable from a key naming standpoint and it's not sane to constantly check the slot (with CLUSTER KEYSLOT in open source or Enterprise in Cluster API mode) when naming keys. The best way to approach this is with some advanced planning and a feature called hash tags. In open source Redis, curly braces ({ and }) are signifiers of a hash tag and the string between these two characters is put through the CRC16 hashing function. Let's take a look at a few examples:

Image title

Given these examples, you can see that Redis would not allow a transaction over keys user-session:1234 and user-profile:1234, but would allow one with user-profile:{1234} and user-session:{1234}.

Note: You might think, "Great, put everything under one hash slot and I won't have to worry about clustered transactions!" You wouldn't be alone, as I've heard this ill-guided plot more than once. Redis won't stop you from doing this or similar things, but you'll end up with an unbalanced cluster, or worse, one full node and many empty nodes. Use hashtags only when needed and, even then, sparingly.

Redis Enterprise can use this strategy but it also adds another feature to make sharding more transparent. Instead of using curly braces, you can use regular expressions to define a particular part of the key to be put through the hashing function. With the regular expression /user\-.*\:(?<tag>.+)/ let's revisit some of our examples from above:

Image title

This regular expression would be flexible enough to also handle other keys that start with "user-", so we could have keys like "user-image" or "user-pagecount". In this scheme, each user's information would be kept on a single hash slot, enabling all sorts of transactions to occur within the scope of a single user.

Let's extend this example a bit further. Say a user changes some information on their profile and we want to update both the profile and session information, and also extend their session so it doesn't expire. Here is a typical (if simplified) version of a transaction:

> MULTI
OK
> HSET user-profile:1234 username "king foo"
QUEUED
> HSET user-session:1234 username "king foo"
QUEUED
> EXPIRE user-session:1234 7200
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1
3) (integer) 1

This would work just fine in Redis Enterprise with the regular expression setup because the hashed portion of both the keys are the same. If you were to run this on open source Redis, you’d need to make sure your keys have curly braces, otherwise, you’d encounter a CROSSSLOT error. The nice thing about this type of error is that Redis will immediately notify you of the invalid transaction/slot crossing violation:

> MULTI
OK
> HSET user-profile:1234 username "king foo"
QUEUED
> HSET user-session:1234 username "king foo"
(error) ERR CROSSSLOT Keys in request don't hash to the same slot (command='HSET', key='user-session:1234') within 'MULTI'
> EXPIRE user-session:1234 7200
(error) ERR CROSSSLOT Keys in request don't hash to the same slot (command='EXPIRE', key='user-session:1234') within 'MULTI'
> EXEC
(error) EXECABORT Transaction discarded because of previous errors.

Keep in mind that some hash slots and key issues are not quite transactions, but are somewhat similar in behavior — single commands that operate over multiple keys. Take this example:

> LPUSH my-list 1 2 3
(integer) 3
> RPOPLPUSH my-list my-new-list
(error) ERR CROSSSLOT Keys in request don't hash to the same slot (command='RPOPLPUSH', key='my-new-list')

RPOPLPUSH is an atomic operation that takes an element off one list and pushes it onto another. The operative word is atomic. If these two lists reside on two different hash slots (much like in a transaction), you'll get the CROSSSLOT error. Open source Redis is quite strict about this and any command that manipulates multiple hash slots is forbidden. Redis Enterprise has a few workarounds for simple commands, notably MGET and MSET.

Getting the Most out of Your Cluster

If you've been a power user of a single instance of Redis, moving to a cluster can feel a bit odd. Some of the commands and/or transactions you've relied on will no longer work on specific keys, and if you're really unlucky, the way you designed your keyspace could be problematic. Here are a few tips for designing your application to work best on a cluster:

  1. Think about the keyspace. Is there a common feature of the key that divides your workload in a smart way (by users, by operation, by time, etc.)? Use hashtags or regular expressions to smartly divvy up the keys into hash slots.
  2. Avoid global state under a single key that needs to be transactionally manipulated, otherwise you're likely to run into CROSSSLOTS errors.
  3. Evaluate your MULTI/EXEC transactions. See if you truly need a transaction or if a pipeline will do. Don't forget to think about multikey commands and whether they can be replaced by multiple commands.
Redis (company) clustering Open source

Published at DZone with permission of Kyle Davis, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Redis-Based Tomcat Session Management
  • Enhancing Performance With Amazon Elasticache Redis: In-Depth Insights Into Cluster and Non-Cluster Modes
  • Scaling Databases With EclipseLink And Redis
  • Automatic Code Transformation With OpenRewrite

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!