Talks

Redis Application Patterns in Rails

Redis Application Patterns in Rails

by Obie Fernandez

In the video "Redis Application Patterns in Rails," speaker Obie Fernandez explores how to effectively use Redis, a high-performance NoSQL database, within Ruby on Rails applications. He shares insights drawn from real production experience at DueProps, demonstrating various Redis application patterns that can enhance scaling and performance over traditional ActiveRecord setups. Key topics include:

  • Overview of Redis: Redis is introduced as a versatile key-value store with rich functionality that simplifies application development.
  • Real-world Problems: Obie discusses his initial challenges with using SQL databases to manage activity streams during a surge in user activity, leading to his adoption of Redis to support scaling.
  • Common Patterns: The talk covers a variety of Redis application patterns, including:
    • Adding Redis-based flags and properties to ActiveRecord objects.
    • Event tracking using Redis sets.
    • Building activity feeds with sorted sets and implementing security restrictions.
    • Aggregation of group activity feeds and usage in scoring and leaderboard features.
    • Integration of Redis with testing frameworks like Rspec and Cucumber.
    • Debugging techniques for troubleshooting Redis interactions.
  • Practical Code Examples: Obie endeavors to provide a hands-on demonstration through live coding, showing how to model data efficiently in Rails while leveraging Redis for improved performance. He presents example code hosted on GitHub for audience reference.
  • Key Takeaways: Obie's conclusion emphasizes the potential of using Redis to manage auxiliary data, thereby streamlining ActiveRecord classes and enhancing application speed. He encourages Rails developers to integrate Redis thoughtfully into their applications to utilize its capabilities effectively without over-complicating their architecture.
00:00:24.730 Hello everyone, I'm here to talk to you about Redis. I was a latecomer to Redis and came to it almost by necessity. I have a company called DueProps, as you can see by my t-shirt. I want to give you a glimpse of what it looks like without this being a plug. It's related to an activity stream, which is common in most applications today. We need to show these streams as events occur throughout the day.
00:00:36.920 Back in October or November, we had a publicity event where we were mentioned and received excellent word of mouth. Initially, my strategy was to avoid premature optimization. So, the app was architected using plain SQL to display these event streams. However, as we began to attract hundreds and then thousands of users, that approach quickly failed. Even adding indexes wasn't sufficient; we needed a more scalable solution, which led me to Redis. The more I used it, the more I realized that it could enhance our application development.
00:00:59.240 So, what is Redis? I can best compare it to Memcached; it's a key-value store but with much richer functionality regarding the basic operations. Setting it up is straightforward and user-friendly. The documentation for Redis is excellent and presents a good example of how its basic functions are enhanced to become more interesting. For instance, the "GETBIT" command allows you to return a bit value and has led me to creatively think about using bit masks in the database. My example code is available on GitHub at 'ob Redis on Rails.' In this talk, I'm aiming to provide not just information about Redis but practical usage scenarios and patterns that you can adapt for your projects.
00:01:39.200 A lot of talks present a new technology, showing you slides with bullets and saying this is why it's cool, but you need to figure everything else out by yourself. What I'm doing here is showcasing practical scenarios with Redis that can serve as a foundation for anyone interested in building projects. My colleague Kay mentioned that you could turn this into a social network, which remains relevant. Startups continue to replicate functionality like this, which makes it useful. I will attempt some live coding today to give you a deeper understanding of how Redis works. I am also going to cover several major categories of Redis commands.
00:02:36.640 For those of you with laptops, I think it will be beneficial to see examples in action. I plan to open a local tunnel using the LocalTunnel gem by Twilio, which is very handy. I will be presenting a sample app running in my development machine, and hopefully it works well. The server has started, and it seems at least a few of you are logging in. While running these experiments, I was pleased to find that performance was very good—the pages were executing in just 20 to 30 milliseconds.
00:03:17.670 The sample application I built models activities similar to what you'd find in a conference organization tool. As you navigate through the site, you can see who has registered for different events, unregister individuals, and even store notes related to those events. You'll notice the activity stream updates in real-time as you perform various actions. I aim to guide you step by step through the primary functionalities and commands of Redis based on our app. I should briefly touch on the importance of keys in both Redis and any key-value store.
00:04:59.950 When dealing with Redis, how you generate and construct your keys is crucial. An effective design allows you to easily look up stored data. It's common practice to reinvent the wheel, and my initial approach led to that frustration. Instead, I recommend using a library called Nest, which simplifies working with Redis connections. This library helps create key representations easily, making your interaction with Redis seamless. It helps structure keys that are intuitive for your application and keeps everything organized.
00:05:46.280 Now, when dealing with nested attributes and keys in Redis, the beauty of using Nest is that it provides a simple, straightforward method for managing key namespaces. For example, I can create a key namespace for users, and by chaining additional keys, I can reference properties associated with those users. This process encourages a clean code structure and enhances maintainability for future updates in your application design.
00:06:43.660 To demonstrate this, I will illustrate how to implement getting and setting string values. Redis allows for the addition of simple attributes to ActiveRecord models, enabling a quick retrieval of attributes directly from Redis while keeping the ActiveRecord structure intact. For example, if I were to add a location to a conference, rather than modifying the existing structure in my database, I'd simply adjust my ActiveRecord model to fetch and store this data from Redis.
00:07:09.470 A key benefit of this approach is that it maintains the lightness of your ActiveRecord objects by reducing the burden of data stored directly in the database. Furthermore, this design encourages a more effective usage of Redis where you can store additional attributes without cluttering your table structure. As I go through some of these examples, you will notice several patterns lend themselves to metaprogramming techniques, which may reduce verbosity in the code.
00:08:15.490 Redis sets and operations like intersections and unions are powerful components of working with your data. You have the ability to model many-to-many relationships more effortlessly than when leveraging ActiveRecord alone. For example, if I want to manage user registrations for a conference without creating complicated join tables, using sets to hold user IDs allows me to maintain a set of attendees on a per-conference basis effortlessly.
00:09:11.600 In examining set operations like "sadd" to add members, "smembers" to fetch all members, and "scard" to retrieve member counts, Redis allows for streamlined data association. This type of modeling is particularly user-friendly and efficient for scenarios like event management, where dynamic attendees may need to be tracked frequently.
00:10:09.420 As I delve deeper into the Redis commands, it’s essential to show how using sorted sets can help with organizing activities in a timely and accessible manner. For instance, utilizing timestamps as scores within the sorted set means we can efficiently track event occurrences in real-time, providing a reliable activity feed for the application.
00:10:42.260 Using sorted sets in this way allows each event to be pushed in a chronological order, which keeps the feed organized and easy to process. When an event occurs within my application, I create an instance of this event class and push that event into the sorted set designated for events. The primary format follows: the key for the set, the score, and the event that corresponds to that score.
00:11:29.970 With the events class set up, I can demonstrate how we utilize various event types leveraging single table inheritance (STI). Here, base events extend into more specific types of events such as 'attendee conference events,' allowing the application to maintain clarity in its object-oriented structure. This encourages clean separation of functionality for each event type while supporting inheritance for shared behaviors.
00:12:30.170 I leverage this architecture to push specific sets of events to different feeds based on the user needs, allowing for customized event displays according to user interactions. Using nested associations, we can query which events belong to a given user or which events belong to a specific conference for an optimal user experience.
00:13:22.640 Next, I will dive deeper into the hash data types within Redis and their applications. Hashes allow you to store multiple fields and values under a single key, effectively mapping attributes to their values in an easily accessible format. This becomes quite useful when we need detailed references for event-related data.
00:14:22.380 When we save data into a hash type, we can access it easily, as shown by managing details associated with events. The operations on hashes mean we can both write and retrieve attributes efficiently, helping maintain concise data structures and improving retrieval times.
00:15:26.000 I will also address potential pitfalls by demonstrating an instance where a naive approach to hashes might lead to confusion, especially with different access methods. This step serves to reinforce best practices for anyone using Redis, ensuring clear paths for data manipulation without unnecessary overhead.
00:16:45.030 Lastly, I'll highlight the Redis props library, which brings together many of these concepts into a simplified format for developers looking to utilize Redis effectively without reinventing the whole solution. By extracting methods that we constantly use when interacting with Redis, we can streamline our approach and reduce boilerplate.
00:17:52.540 Utilizing the Redis props library means you can annotate objects directly with attributes that will map to Redis keys seamlessly. This results in a user-friendly interface for handling Redis interactions while focusing on business logic rather than low-level implementation details.
00:19:04.520 As we loop back to the subject of performance, Redis operators allow efficient management of data, maintaining impressive speeds. This performance optimization plays a crucial role as your dataset grows. Given that Redis operates in-memory, it dramatically reduces access time compared to traditional databases.
00:20:06.250 To close, I encourage you to explore the potential within Redis as applied to real-world challenges involving scalability and performance optimization. With proper implementation patterns, Redis can amplify your applications from a performance standpoint, while not compromising data management.
00:21:12.620 Your experience with Redis will undoubtedly evolve over time. This evolution might include adjustments to the way you manage Redis alongside traditional databases like PostgreSQL. Many applications today still lean on both technologies in tandem, allowing them to capture benefits from both domains.
00:22:22.560 If you're looking for a way to implement activity tracking in your application, Redis' capabilities present an efficient solution. By understanding how to utilize its foundational constructs such as sets, sorted sets, and hashes, you can significantly enhance your application's responsiveness and scalability.
00:23:32.330 Concluding this talk, I'm available for questions related to Redis and how it integrates with Rails applications. The depth of Redis in real-world scenarios is vast, and I’m eager to hear about your experiences and explore how we can optimize your projects further.