YARR - Yet Another Redis Record
Redis Record provides an object-relational mapping like Active Record, but for Redis.
Note: This is a pre-release version.
1. Add yarr to your Gemfile
# -- Gemfile -- gem 'yarr'
2. Connect to a Redis server
config/redis_record.yml, set a default Redis URL for all Redis Record models in the test and development environment. Note: the local Redis server version needs to be >= 4.x.
development: default: url: redis://127.0.0.1:6379/1 test: default: url: redis://127.0.0.1:6379/2
Learn more: Redis Server Configurations
3. Create a Redis Record model
In the example, we create a UserSession model -- The in-memory Redis database is great for session management.
class UserSession < T::Struct include :: ttl 2.hours attribute :user_id, Integer, index: true attribute :session_id, String end
Learn more: Redis Record Model
4. Reading and writing data
Return the first user session that matches the user's id:
UserSession.find_by(user_id: user.id) # TODO: support this
Note: This query won’t work until we execute a Redis Record migration for adding the index.
Like Active Record, created_at and updated_at are maintained automatically on each record. Find all user sessions created an hour ago:
UserSession.where('created_at < ?', Time.zone.now - 1.hour) # TODO: support this
Once a Redis Record object has been retrieved, its attributes can be modified and it can be saved to the Redis database.
user_session = UserSession.find_by(user_id: user.id) user_session.updated_at = Time.zone.now user_session.save # TODO: support this
A shorthand for this is to use a hash mapping attribute names to the desired value:
user_session.update(updated_at: Time.zone.now) # TODO: support this
Once a Redis Record object has been retrieved, it can be destroyed which removes it from the database.
user_session = UserSession.find_by(user_id: user.id) user_session.destroy
Learn more: Querying interface
Redis Record provides a domain-specific language for updating model schemas on Redis called migrations. Migrations are stored in files which are executed against each Redis database used in the current Rails environment.
Here's a migration that adds an index on user_id and adds a TTL on each user session:
TODO: db/redisrecord -> db/redis_record
class CreateUserSession < :: def up change_ttl_passive(UserSession) add_index(UserSession, :user_id) end def down change_ttl_passive(UserSession, nil) remove_index(UserSession, :user_id) end end
Use the following rake command to run this migration
$ rake redis:migrate redis direction version migration duration redis://127.0.0.1:6379/0 UP 20200504000000 Create user session 18.03934400959406 ms Finished in 0.024 second
Learn more: Migrations
Related Projects; Yet Another Redis Record
To the best of our knowledge, YARR is the best Ruby ORM lib for Redis.
This project is inspired by ohm. YARR has the following features which Ohm does not have:
- An Active Record like API
- Range index queries support
- Atomic CRUD operations
- Runtime and statical type-checking (with sorbet)
- One Redis DB roundtrip per operation
- Migrations and push safety protection
Redis object map Redis types directly to Ruby objects, but it does not provide an object-relational mapping.
- RediSQL is not ORM
- RediSQL does not support indexing
- RediSQL uses a Redis server extension, which is not supported by all Redis PaaSs. Redis Record uses Lua scripts that are generally supported.
Redis Record is fast!
TODO: Comparison with Postgres
TODO: Benchmark results
We recommend using Redis Record on a Redis PaaS which has built-in failover support. If a Redis server is down, there will be downtime, but the Redis Platform would hopefully recover quickly.
- Set the Redis server to noevict
- (optional) Take screenshots of the server regularly
- Do not use Redis Cluster
- Rely on fail-over instead of AOF persistency
Contributions and ideas are welcome! Please see our contributing guide and don't hesitate to open an issue or send a pull request to improve the functionality of this gem. This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to [email protected].
This project is licensed under MIT.