Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Writing Redis Module with Rust

619 views

Published on

#COSCUP 2017

Published in: Technology
  • Be the first to comment

Writing Redis Module with Rust

  1. 1. Writing Redis Module with Rust
  2. 2. Writing Critical Systems ina distractedworld
  3. 3. Database isaCriticalSystem » Single source of truth » Scaling is hard » Requires high performance » Must be stable
  4. 4. Adistractedworld Typical Web dev: » 95% business logic: Ruby/Python/Javascript » 5% optimization » Mean time between optimization: 3+ months
  5. 5. Poga » github.com/poga » poga.po@gmail.com » Consultant » Web, Distributed System, P2P, Decentralization
  6. 6. Redis » Fast, In-Memory Database » Simple to Reason About » NoSQL/Cache/Message Broker » Cluster/Replication » Extensible with Redis Module API
  7. 7. Redis Redis is being used as » Atomic Lock » Cache » Message Broker » Big Data + AI ...requires safe, stable, and efficient implementation
  8. 8. Redis Module » Move Code to Data » Free Redis Protocol » Free Memory management/Serialization » Free Replication/Clustering » C API
  9. 9. CAPI is scary » Memory Safety? » Undefined Behaviour? » Dependency? Include?
  10. 10. You need Focus Towrite safe C code
  11. 11. ...butwe onlyhave 5% Focus
  12. 12. Rust » borrow checker: a smart and severe mentor » cargo: simple dependency management » Stable release cycle The system won't collapse when you reopen it 3 month later
  13. 13. rustc is never distracted
  14. 14. WritingaRedis Module
  15. 15. build our own lib from redismodule.h Redis doesn't provide a lib, only a header file #include "redismodule.h" int Export_RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver) { return RedisModule_Init(ctx, name, ver, apiver); }
  16. 16. build our own lib from redismodule.h build.rs: Compile C/C++ code into a Rust lib extern crate gcc; fn main() { gcc::Config::new() .file("src/redismodule.c") .include("include/") .compile("libredismodule.a"); }
  17. 17. Static linking #[derive(Clone, Copy)] #[repr(C)] pub struct RedisModuleCtx; #[allow(improper_ctypes)] #[link(name="redismodule", kind="static")] extern "C" { pub fn Export_RedisModule_Init(ctx: *mut RedisModuleCtx, modulename: *const u8, module_version: c_int, api_version: c_int) -> Status; // ... }
  18. 18. Free resourcewith Droptrait » RedisModuleString: string type provided by Redis » Need to be explicitly freed when you're done. pub struct RedisString { ctx: *mut raw::RedisModuleCtx, str_inner: *mut raw::RedisModuleString, }
  19. 19. Free resourcewith Droptrait impl RedisString { fn create(ctx: *mut raw::RedisModuleCtx, s: &str) -> RedisString { let str_inner = raw::create_string(ctx, format!("{}0", s).as_ptr(), s.len()); // ... } } impl Drop for RedisString { // Frees resources appropriately as a RedisString goes out of scope. fn drop(&mut self) { raw::free_string(self.ctx, self.str_inner); } }
  20. 20. Function Pointer typedef int (*RedisModuleCmdFunc) (RedisModuleCtx *ctx, RedisModuleString **argv, int argc); int REDISMODULE_API_FUNC( RedisModule_CreateCommand )(..., RedisModuleCmdFunc cmdfunc, ...)
  21. 21. Function Pointer Use Option pub type RedisModuleCmdFunc = extern "C" fn( ctx: *mut RedisModuleCtx, argv: *mut *mut RedisModuleString, argc: c_int) -> Status; static RedisModule_CreateCommand: extern "C" fn( ..., cmdfunc: Option<RedisModuleCmdFunc>, ...)
  22. 22. Performance “Informal benchmarks show that redis-cell is pretty fast, taking a little under twice as long to run as a basic Redis SET” https://github.com/brandur/redis-cell
  23. 23. Recap
  24. 24. Redis Module: » Free Protocol » Free Performance » Free Serialization » Free Replication
  25. 25. Rust: write safe code inadistractedworld
  26. 26. Developer: Focus on Business Logic and Happiness
  27. 27. be Fearless
  28. 28. References » Redis-cell: github.com/brandur/redis-cell » rate-limiting » Redis-rating: github.com/poga/redis-rating » average rating
  29. 29. Thanks

×