Rust and Redis
(and Protobuf, oh my!)
Nell Shamrell-Harrington
Redis Seattle Meetup
Redis and Rust @nellshamrell
• Sr. Software Engineer at Chef
• Core maintainer of Habitat
• Food Fight Show Co-Host
• @nellshamrell
• nshamrell@chef.io
Nell Shamrell-Harrington
Redis and Rust @nellshamrell
• Epic Rust and Redis adventure with Habitat
Why am I here?
Redis and Rust @nellshamrell
• Habitat 101
• Rust 101
• Redis and Rust
• Protobuf
• Converting from Redis to Postgres
What will we talk about tonight?
Habitat 101
Ch. 1 of 5
Habitat is a new technology to
build, deploy, and manage
applications…
…in any environment from
traditional datacenters to
containerized microservices
Redis and Rust @nellshamrell
Packaging and Application with Habitat
User
Workstation
Redis and Rust @nellshamrell
Packaging and Application with Habitat
ç
User Plan
Bash (available now)
PowerShell (soon!)
Workstation
Redis and Rust @nellshamrell
Packaging and Application with Habitat
ç
User Plan Artifact
Bash (available now)
PowerShell (soon!)
Signed with a keyWorkstation
Redis and Rust @nellshamrell
Packaging an Application with Habitat
ç
User Plan Artifact Depot
Bash (available now)
PowerShell (soon!)
Signed with a key
(Optional)
Workstation
Redis and Rust @nellshamrell
Running an Application with Habitat
Depot
(Optional)
Redis and Rust @nellshamrell
Running an Application with Habitat
ArtifactDepot
(Optional)
Redis and Rust @nellshamrell
Running an Application with Habitat
ArtifactDepot
(Optional)
Bare Metal
Virtual Machine
Container
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Habitat
Supervisor
(Runs Services)
Habitat Package
(Run as a Service)
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
Virtual Machine
MySql
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
Virtual Machine
MySql
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
Virtual Machine
MySql
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
Virtual Machine
MySql
We need a leader!
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
Virtual Machine
MySql
Let’s hold an election!
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
Virtual Machine
MySql
Leader
Followers
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
Virtual Machine
MySql
.nvmrc
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
We need a leader!
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
Let’s hold an election!
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
Leader
Redis and Rust @nellshamrell
Running an Application with Habitat
Virtual Machine
MySql
Virtual Machine
MySql
Follower
Habitat is written in Rust
Rust 101
Ch. 2 of 5
Rust focuses on safety,
speed, and concurrency…
It performs the majority of its
safety checks and memory
managment decisions at
compile time…
So your program’s runtime
performance is not impacted
Redis and Rust @nellshamrell
main.rs
1. fn main() {
2. println!(“Hello, World!”);
3. }
Redis and Rust @nellshamrell
• Crate is synonymous with ‘library’ or ‘package’
• Rust’s package management tool is called “Cargo”
Rust libraries are called crates
Redis and Rust @nellshamrell
Cargo.toml
1. [package]
2. name = “habitat_depot”
3. version = “0.1.0”
4. authors = [“Nell Shamrell-Harrington <nshamrell@chef.io>"]
5.
6. [dependencies]
7. hyper = “*”
8. iron = “*”
Redis and Rust
Ch. 3 of 5
Early versions of Habitat
used Redis as a
persistant data store
Eventually, this data needed
to be migrated to Postgres
Why did you use Redis as a
persistant data store?
It was the best decision at the time to
meet a deadline…
I do not personally recommend
this approach…
…But we can learn a lot
from the story.
First step in migrating…how do we
get the data out of Redis?
Redis and Rust @nellshamrell
Redis libraries for Rust
Redis and Rust @nellshamrell
main.rs
1. extern crate redis;
2. use redis::Commands;
Redis and Rust @nellshamrell
main.rs
1. extern crate redis;
2. use redis::Commands;
3.
4. fn main() {
5. let client = redis::Client::open(“redis://127.0.0.1/“).unwrap();
6. }
Redis and Rust @nellshamrell
main.rs
1. extern crate redis;
2. use redis::Commands;
3.
4. fn main() {
5. let client = redis::Client::open(“redis://127.0.0.1/“).unwrap();
6.
7. client.lpush(“users”, “Sylvanas”)?;
8. }
Redis and Rust @nellshamrell
main.rs
1. extern crate redis;
2. use redis::Commands;
3.
4. fn main() {
5. let client = redis::Client::open(“redis://127.0.0.1/“).unwrap();
6.
7. client.lpush(“users”, “Sylvanas”)?;
8.
9. let users_list = client.lrange(“users”, 0, -1).unwrap();
10. }
Redis and Rust @nellshamrell
main.rs
1. extern crate redis;
2. use redis::Commands;
3.
4. fn main() {
5. let client = redis::Client::open(“redis://127.0.0.1/“).unwrap();
6.
7. client.lpush(“users”, “Sylvanas”)?;
8.
9. let users_list = client.lrange(“users”, 0, -1).unwrap();
10. let data_results = redis::from_redis_value(…)
11. data_results[0]
12. }
Next…how do we get in Postgres?
Redis and Rust @nellshamrell
main.rs
1. extern crate redis;
2. use redis::Commands;
3.
4. extern crate postgres;
5. use postgres::{Connection, TlsMode};
6.
7. fn main() {
8. (…)
9. }
Redis and Rust @nellshamrell
main.rs
1. fn main() {
2. (…)
3. let postgres_connection = Connection::connect(“games://
4. postgres_username@localhost”, TlsMode::None).unwrap();
3.
Redis and Rust @nellshamrell
main.rs
1. fn main() {
2. (…)
3. let postgres_connection = Connection::connect(“games://
4. postgres_username@localhost”, TlsMode::None).unwrap();
3.
4. for row in data_results {
5. let user = User { name: row };
Redis and Rust @nellshamrell
main.rs
1. fn main() {
2. (…)
3. let postgres_connection = Connection::connect(“games://
4. postgres_username@localhost”, TlsMode::None).unwrap();
3.
4. for row in data_results {
5. let user = User { name: row };
6.
7. postgres_connection
8. .execute("INSERT INTO users (name) VALUES ($1)",
9. &[&user.name])
10. }
Redis and Rust @nellshamrell
githhub.com/nellshamrell/redis-to-postgres-migrator
Let’s do it with the
Habitat Redis Store!
Redis and Rust @nellshamrell
Console
$ redis-cli
Redis and Rust @nellshamrell
Console
$ redis-cli
127.0.0.1:6379> MGET "account:250768796355682371"
Redis and Rust @nellshamrell
Console
$ redis-cli
127.0.0.1:6379> MGET "account:250768796355682371"
“bxc3xc0xa1x9cxc4x9cxbaxbdx03x12x11co
rey@coreygo.comx1aacoreygo”
The data was serialized!
Habitat is made of
microservices…
…which need to transmit data
among each other…
…this data is serialized
with Protobuf
Protobuf 101
Ch. 4 of 5
Redis and Rust @nellshamrell
Data Serialization
Sender
Redis and Rust @nellshamrell
Data Serialization
Sender
Data!
Redis and Rust @nellshamrell
Data Serialization
Sender
Data! Serialize with Protobuf!
Redis and Rust @nellshamrell
Data Serialization
Sender
Binary Data
Redis and Rust @nellshamrell
Data Serialization
Sender Reciever
Network
Connection
Redis and Rust @nellshamrell
Data Serialization
Sender Reciever
Unserialize
with Protobuf!
Redis and Rust @nellshamrell
Data Serialization
Sender Reciever
Data!
How do you code it?
Redis and Rust @nellshamrell
person.proto
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
}
Redis and Rust @nellshamrell
person.proto
Protbuf
Redis and Rust @nellshamrell
person.proto
Compiler for
Language
of Choice
Protbuf
Redis and Rust @nellshamrell
person.proto
Compiler for
Language
of Choice
Serialization
Code in
Language
of Choice
Protbuf
Redis and Rust @nellshamrell
Protobuf library for Rust
Converting from
Redis to Postgres
Ch. 5 of 5
Can I map from redis
to postgres 1:1?
Unfortunately, no…
Redis and Rust @nellshamrell
Habitat 0.12.1
Protocols
depotsrv.proto
jobsrv.proto
net.proto
routesrv.proto
sessionsrv.proto
vault.proto
Habitat 0.24.0
Protocols
jobsrv.proto
net.proto
originsrv.proto
routesrv.proto
scheduler.proto
sessionsrv.proto
Ok, let’s use both sets of protocols
Redis and Rust @nellshamrell
Redis DB
0.12.1
Protocols
Migrator
0.24.0
Protocols
Postgres DB
But…processing the data takes
multiple microservices
For both versions of Habitat
Redis and Rust @nellshamrell
Redis
DB
0.12.1
Microservices
Migrator
0.24.0
Microservices
Postgres
DB
Redis and Rust @nellshamrell
github.com/habitat-sh/redis-postgres-migrator
Redis and Rust @nellshamrell
• Sr. Software Engineer at Chef
• Core maintainer of Habitat
• Food Fight Show Co-Host
• @nellshamrell
• nshamrell@chef.io
Nell Shamrell-Harrington

Rust, Redis, and Protobuf - Oh My!

  • 1.
    Rust and Redis (andProtobuf, oh my!) Nell Shamrell-Harrington Redis Seattle Meetup
  • 2.
    Redis and Rust@nellshamrell • Sr. Software Engineer at Chef • Core maintainer of Habitat • Food Fight Show Co-Host • @nellshamrell • nshamrell@chef.io Nell Shamrell-Harrington
  • 3.
    Redis and Rust@nellshamrell • Epic Rust and Redis adventure with Habitat Why am I here?
  • 4.
    Redis and Rust@nellshamrell • Habitat 101 • Rust 101 • Redis and Rust • Protobuf • Converting from Redis to Postgres What will we talk about tonight?
  • 5.
  • 6.
    Habitat is anew technology to build, deploy, and manage applications…
  • 7.
    …in any environmentfrom traditional datacenters to containerized microservices
  • 8.
    Redis and Rust@nellshamrell Packaging and Application with Habitat User Workstation
  • 9.
    Redis and Rust@nellshamrell Packaging and Application with Habitat ç User Plan Bash (available now) PowerShell (soon!) Workstation
  • 10.
    Redis and Rust@nellshamrell Packaging and Application with Habitat ç User Plan Artifact Bash (available now) PowerShell (soon!) Signed with a keyWorkstation
  • 11.
    Redis and Rust@nellshamrell Packaging an Application with Habitat ç User Plan Artifact Depot Bash (available now) PowerShell (soon!) Signed with a key (Optional) Workstation
  • 12.
    Redis and Rust@nellshamrell Running an Application with Habitat Depot (Optional)
  • 13.
    Redis and Rust@nellshamrell Running an Application with Habitat ArtifactDepot (Optional)
  • 14.
    Redis and Rust@nellshamrell Running an Application with Habitat ArtifactDepot (Optional) Bare Metal Virtual Machine Container
  • 15.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql
  • 16.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Habitat Supervisor (Runs Services) Habitat Package (Run as a Service)
  • 17.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql Virtual Machine MySql
  • 18.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql Virtual Machine MySql
  • 19.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql Virtual Machine MySql
  • 20.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql Virtual Machine MySql We need a leader!
  • 21.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql Virtual Machine MySql Let’s hold an election!
  • 22.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql Virtual Machine MySql Leader Followers
  • 23.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql Virtual Machine MySql .nvmrc
  • 24.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql
  • 25.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql We need a leader!
  • 26.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql Let’s hold an election!
  • 27.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql Leader
  • 28.
    Redis and Rust@nellshamrell Running an Application with Habitat Virtual Machine MySql Virtual Machine MySql Follower
  • 29.
  • 30.
  • 31.
    Rust focuses onsafety, speed, and concurrency…
  • 32.
    It performs themajority of its safety checks and memory managment decisions at compile time…
  • 33.
    So your program’sruntime performance is not impacted
  • 34.
    Redis and Rust@nellshamrell main.rs 1. fn main() { 2. println!(“Hello, World!”); 3. }
  • 35.
    Redis and Rust@nellshamrell • Crate is synonymous with ‘library’ or ‘package’ • Rust’s package management tool is called “Cargo” Rust libraries are called crates
  • 36.
    Redis and Rust@nellshamrell Cargo.toml 1. [package] 2. name = “habitat_depot” 3. version = “0.1.0” 4. authors = [“Nell Shamrell-Harrington <nshamrell@chef.io>"] 5. 6. [dependencies] 7. hyper = “*” 8. iron = “*”
  • 37.
  • 38.
    Early versions ofHabitat used Redis as a persistant data store
  • 39.
    Eventually, this dataneeded to be migrated to Postgres
  • 40.
    Why did youuse Redis as a persistant data store? It was the best decision at the time to meet a deadline…
  • 41.
    I do notpersonally recommend this approach…
  • 42.
    …But we canlearn a lot from the story.
  • 43.
    First step inmigrating…how do we get the data out of Redis?
  • 44.
    Redis and Rust@nellshamrell Redis libraries for Rust
  • 45.
    Redis and Rust@nellshamrell main.rs 1. extern crate redis; 2. use redis::Commands;
  • 46.
    Redis and Rust@nellshamrell main.rs 1. extern crate redis; 2. use redis::Commands; 3. 4. fn main() { 5. let client = redis::Client::open(“redis://127.0.0.1/“).unwrap(); 6. }
  • 47.
    Redis and Rust@nellshamrell main.rs 1. extern crate redis; 2. use redis::Commands; 3. 4. fn main() { 5. let client = redis::Client::open(“redis://127.0.0.1/“).unwrap(); 6. 7. client.lpush(“users”, “Sylvanas”)?; 8. }
  • 48.
    Redis and Rust@nellshamrell main.rs 1. extern crate redis; 2. use redis::Commands; 3. 4. fn main() { 5. let client = redis::Client::open(“redis://127.0.0.1/“).unwrap(); 6. 7. client.lpush(“users”, “Sylvanas”)?; 8. 9. let users_list = client.lrange(“users”, 0, -1).unwrap(); 10. }
  • 49.
    Redis and Rust@nellshamrell main.rs 1. extern crate redis; 2. use redis::Commands; 3. 4. fn main() { 5. let client = redis::Client::open(“redis://127.0.0.1/“).unwrap(); 6. 7. client.lpush(“users”, “Sylvanas”)?; 8. 9. let users_list = client.lrange(“users”, 0, -1).unwrap(); 10. let data_results = redis::from_redis_value(…) 11. data_results[0] 12. }
  • 50.
    Next…how do weget in Postgres?
  • 51.
    Redis and Rust@nellshamrell main.rs 1. extern crate redis; 2. use redis::Commands; 3. 4. extern crate postgres; 5. use postgres::{Connection, TlsMode}; 6. 7. fn main() { 8. (…) 9. }
  • 52.
    Redis and Rust@nellshamrell main.rs 1. fn main() { 2. (…) 3. let postgres_connection = Connection::connect(“games:// 4. postgres_username@localhost”, TlsMode::None).unwrap(); 3.
  • 53.
    Redis and Rust@nellshamrell main.rs 1. fn main() { 2. (…) 3. let postgres_connection = Connection::connect(“games:// 4. postgres_username@localhost”, TlsMode::None).unwrap(); 3. 4. for row in data_results { 5. let user = User { name: row };
  • 54.
    Redis and Rust@nellshamrell main.rs 1. fn main() { 2. (…) 3. let postgres_connection = Connection::connect(“games:// 4. postgres_username@localhost”, TlsMode::None).unwrap(); 3. 4. for row in data_results { 5. let user = User { name: row }; 6. 7. postgres_connection 8. .execute("INSERT INTO users (name) VALUES ($1)", 9. &[&user.name]) 10. }
  • 55.
    Redis and Rust@nellshamrell githhub.com/nellshamrell/redis-to-postgres-migrator
  • 56.
    Let’s do itwith the Habitat Redis Store!
  • 57.
    Redis and Rust@nellshamrell Console $ redis-cli
  • 58.
    Redis and Rust@nellshamrell Console $ redis-cli 127.0.0.1:6379> MGET "account:250768796355682371"
  • 59.
    Redis and Rust@nellshamrell Console $ redis-cli 127.0.0.1:6379> MGET "account:250768796355682371" “bxc3xc0xa1x9cxc4x9cxbaxbdx03x12x11co rey@coreygo.comx1aacoreygo”
  • 60.
    The data wasserialized!
  • 61.
    Habitat is madeof microservices…
  • 62.
    …which need totransmit data among each other…
  • 63.
    …this data isserialized with Protobuf
  • 64.
  • 65.
    Redis and Rust@nellshamrell Data Serialization Sender
  • 66.
    Redis and Rust@nellshamrell Data Serialization Sender Data!
  • 67.
    Redis and Rust@nellshamrell Data Serialization Sender Data! Serialize with Protobuf!
  • 68.
    Redis and Rust@nellshamrell Data Serialization Sender Binary Data
  • 69.
    Redis and Rust@nellshamrell Data Serialization Sender Reciever Network Connection
  • 70.
    Redis and Rust@nellshamrell Data Serialization Sender Reciever Unserialize with Protobuf!
  • 71.
    Redis and Rust@nellshamrell Data Serialization Sender Reciever Data!
  • 72.
    How do youcode it?
  • 73.
    Redis and Rust@nellshamrell person.proto message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } }
  • 74.
    Redis and Rust@nellshamrell person.proto Protbuf
  • 75.
    Redis and Rust@nellshamrell person.proto Compiler for Language of Choice Protbuf
  • 76.
    Redis and Rust@nellshamrell person.proto Compiler for Language of Choice Serialization Code in Language of Choice Protbuf
  • 77.
    Redis and Rust@nellshamrell Protobuf library for Rust
  • 78.
    Converting from Redis toPostgres Ch. 5 of 5
  • 79.
    Can I mapfrom redis to postgres 1:1?
  • 80.
  • 81.
    Redis and Rust@nellshamrell Habitat 0.12.1 Protocols depotsrv.proto jobsrv.proto net.proto routesrv.proto sessionsrv.proto vault.proto Habitat 0.24.0 Protocols jobsrv.proto net.proto originsrv.proto routesrv.proto scheduler.proto sessionsrv.proto
  • 82.
    Ok, let’s useboth sets of protocols
  • 83.
    Redis and Rust@nellshamrell Redis DB 0.12.1 Protocols Migrator 0.24.0 Protocols Postgres DB
  • 84.
    But…processing the datatakes multiple microservices
  • 85.
  • 86.
    Redis and Rust@nellshamrell Redis DB 0.12.1 Microservices Migrator 0.24.0 Microservices Postgres DB
  • 87.
    Redis and Rust@nellshamrell github.com/habitat-sh/redis-postgres-migrator
  • 88.
    Redis and Rust@nellshamrell • Sr. Software Engineer at Chef • Core maintainer of Habitat • Food Fight Show Co-Host • @nellshamrell • nshamrell@chef.io Nell Shamrell-Harrington