SlideShare a Scribd company logo
1 of 26
Download to read offline
START
job "A"
I/O
stdin,
stdout, …
SSH
session "X"
SEND
queue "A:X"
LISTEN
queue "X:A"
AUTHORIZE
HTTP
SSE
Architecture
for SSH I/O
streaming
SSH I/O streaming via Redis-based
persistent message queue
Mani Tadayon

RedisConf 2016
About me
• @bwsr_sr

• Working in software since ’01

• Using Redis since ’13

<shameless-plug>
• Just finished a book on Ruby
testing: RSpec Essentials

• http://amzn.com/1784395900

</shameless-plug>
How to build a message
queue with Redis
• Live listener

> subscribe mychannel
• Publisher

> publish mychannel mymessage
And that’s my talk, thanks for listening!
DoDo’s mad!
– http://antirez.com/news/88
“Redis apparently is at the same time the best
and the worst system to use like that.”
Demo
START
job "A"
I/O
stdin,
stdout, …
SSH
host "X"
SEND
queue "A:X"
LISTEN
queue “A:X”
AUTHORIZE
HTTP
SSE
Architecture
for SSH I/O
streaming
How to build a persistent
message queue with Redis
• Retrieve persisted messages

> lrange mykey 0 -1
• Publisher

> rpush mykey mymessage

What about a live listener?
The best of both worlds
• Live listener

> subscribe mychannel
• Retrieve persisted messages

> lrange mykey 0 -1
• Publisher

> rpush mykey mymessage

> publish mychannel mymessage

That’s pretty much it. But the SSH I/O feature needs a few more features.
• Lookup by session ID (“A:X”)

• Use a simple list of key names

> rpush byjob mykey
> expire byjob 604800
• Lookup by hostname (“A:*”)

• Use a zset with timestamp as score

> zadd byhost 1463012431 mykey
> zremrangebyscore byhost 0 1462407631
• Wrap each message in a transaction

• Protect against excessive memory usage (150GB in 2 hours on the 1st day…)

• Limit number of persisted messages per job

• Expire persisted messages (more aggressively for verbose jobs)

• Stop sending messages above a threshold (handled outside Redis)

> multi
> rpush mykey mymessage
> expire mykey 604800
> ltrim mykey -100 -1
> publish mychannel mymessage
> exec
• Set up indexes for lookup (only once per job)

> rpush byjob mykey
> expire byjob 604800
> zadd byhost 1463012431 mykey
> zremrangebyscore byhost 0 1462407631
Key and channel names
ssh-io:session:event:persisted:$ID:$FQDN
ssh-io:session:event:live:$ID:$FQDN
ssh-io:session:event_lookup:by_job:$ID
ssh-io:session:event_lookup:by_hostname:$FQDN
> multi
> rpush ssh-io:session:event:persisted:b8042948:fakehost.example.com
{"session_started":"About to run 4 commands on fakehost.example.com for
CustomScript-
TestStreamingSimple:b8042948","io_type":"session_started","timestamp":1462407631}
> expire ssh-io:session:event:persisted:b8042948:fakehost.example.com 604800
> ltrim ssh-io:session:event:persisted:b8042948:fakehost.example.com -100 -1
> publish ssh-io:session:event:live:b8042948:fakehost.example.com
{"session_started":"About to run 4 commands on fakehost.example.com for
CustomScript-
TestStreamingSimple:b8042948","io_type":"session_started","timestamp":1462407631}
> exec
> rpush ssh-io:session:event_lookup:by_job:b8042948 ssh-
io:session:event:persisted:b8042948:fakehost.example.com
> expire ssh-io:session:event_lookup:by_job:b8042948 604800
> zadd ssh-io:session:event_lookup:by_hostname:fakehost.example.com 1463012431 ssh-
io:session:event:persisted:b8042948:fakehost.example.com
> zremrangebyscore ssh-io:session:event_lookup:by_hostname:fakehost.example.com 0
1462407631
> multi
> rpush ssh-io:session:event:persisted:b8042948:fakehost.example.com
{"username":"deploy","stdin":"echo "ping number
1"","hostname":"fakehost.example.com","io_type":"stdin","timestamp":1462407631}
> expire ssh-io:session:event:persisted:b8042948:fakehost.example.com 604800
> ltrim ssh-io:session:event:persisted:b8042948:fakehost.example.com -100 -1
> publish ssh-io:session:event:live:b8042948:fakehost.example.com
{"username":"deploy","stdin":"echo "ping number
1"","hostname":"fakehost.example.com","io_type":"stdin","timestamp":1462407631}
> exec
# … multi,rpush,expire,ltrim,publish,exec …
> multi
> rpush ssh-io:session:event:persisted:b8042948:fakehost.example.com {"session_finished":"Ran 4
of 4 commands on fakehost.example.com for CustomScript-
TestStreamingSimple:b8042948","success":false,"io_type":"session_finished","timestamp":
1462407631}
> expire ssh-io:session:event:persisted:b8042948:fakehost.example.com 604800
> ltrim ssh-io:session:event:persisted:b8042948:fakehost.example.com -100 -1
> publish ssh-io:session:event:live:b8042948:fakehost.example.com {"session_finished":"Ran 4 of
4 commands on fakehost.example.com for CustomScript-
TestStreamingSimple:b8042948","success":false,"io_type":"session_finished","timestamp":
1462407631}
Lookup by hostname
• Lua script that uses the zset index

• Returns all events, in order, per hostname
$ redis-cli zrange ssh-io:session:event_lookup:by_hostname:fakehost.example.com 0 -1

1) "ssh-io:session:event:persisted:0bd6005b-1999-42ab-9b54-2585e0383bcb:fakehost.example.com"

2) "ssh-io:session:event:persisted:84ae935f-55a2-4210-a356-87a0da7c3b58:fakehost.example.com"

3) "ssh-io:session:event:persisted:35696242-a59d-4a1f-b36f-4ee988b558c5:fakehost.example.com"

4) "ssh-io:session:event:persisted:b72488ec-816c-48b9-a48d-ab31cbc41802:fakehost.example.com"

5) "ssh-io:session:event:persisted:5b13b4bd-2800-47fe-a821-a548c90054b6:fakehost.example.com"

6) "ssh-io:session:event:persisted:26078a92-e349-43a7-9375-d0ce511b1dbd:fakehost.example.com"

7) "ssh-io:session:event:persisted:4c3f31f0-dd2d-411f-bfbe-d6591698bf3a:fakehost.example.com"

8) "ssh-io:session:event:persisted:60983166-f580-44d6-9058-3b8bb04c1441:fakehost.example.com"

9) "ssh-io:session:event:persisted:572de4a5-3d15-4160-ab42-006407662ca8:fakehost.example.com"

10) "ssh-io:session:event:persisted:3b405df9-3618-4cc2-b245-4dac4b7a203b:fakehost.example.com"

11) "ssh-io:session:event:persisted:5968f887-9228-4963-9515-b92eda944063:fakehost.example.com"

12) "ssh-io:session:event:persisted:ebcd6068-4a22-48f1-a333-36a312bb78f0:fakehost.example.com"

13) "ssh-io:session:event:persisted:d22ae42d-4343-46b8-a477-8fa057bc34b5:fakehost.example.com"

14) "ssh-io:session:event:persisted:49c994db-9d3d-4453-ac83-8dbf038a655d:fakehost.example.com"

15) "ssh-io:session:event:persisted:2fc5ea10-c8f8-42e7-93d4-073b68826ffa:fakehost.example.com"

16) "ssh-io:session:event:persisted:b8042948-63f1-4c6f-afc8-8d2384b3b155:fakehost.example.com"

17) "ssh-io:session:event:persisted:5fee9662-af66-4027-9963-ff59716dc7e0:fakehost.example.com"

18) "ssh-io:session:event:persisted:c919f801-ab8b-4f31-92f8-3f51d6b7b7dc:fakehost.example.com"

19) "ssh-io:session:event:persisted:22f480d9-31cb-4054-9861-51d0275c9468:fakehost.example.com"

20) "ssh-io:session:event:persisted:7710e61f-921c-4d6d-bbf4-e9c35d932f1a:fakehost.example.com"
-- finds the keys for all sessions for... 

-- ...a given hostname using lookup lists,

-- then retrieve all events in all keys

-- use nested numeric lua tables (i.e. arrays)...

-- ...since redis will wipe out string keys

-- see: http://redis.io/commands/eval 

-- (Conversion between Lua and Redis data types)


local keys = redis.call("zrange", KEYS[1], 0, -1)

local returner = {}

for i, key in ipairs(keys) do

returner[i] = {

key,

redis.call("lrange", key, 0, -1)

}

end

return returner

$ redis-cli eval "$(cat values-from-lookup-set.lua)" 

1 
ssh-io:session:event_lookup:by_hostname:fakehost.example.com



1) 1) "ssh-io:session:event:persisted:
0bd6005b-1999-42ab-9b54-2585e0383bcb:fakehost.example.com"

2) 1) "{"session_started":"About to run 4 commands on
fakehost.example.com for :0bd6005b-1999-42ab-9b54-2585e0383bcb","io_type":
"session_started","timestamp":1462405267}"



# … 18 more sessions …



20) 1) "ssh-io:session:event:persisted:7710e61f-921c-4d6d-bbf4-
e9c35d932f1a:fakehost.example.com"

2) 1) "{"session_started":"About to run 6 commands on
fakehost.example.com for CustomScript-TestStreamingSimple:7710e61f-921c-4d6d-
bbf4-e9c35d932f1a","io_type":"session_started","timestamp":1462524784}"
Authentication
• From browser directly to node.js web service

• Web app creates an auth token

• Token written to Redis…

• …and stored in browser session

• 1 day expiry

• Simple Lua script to create or retrieve token
local token = ''



if redis.call('exists', KEYS[1]) == 1
then

token = redis.call('get', KEYS[1])

else

redis.call('setex', KEYS[1], ARGV[1],
ARGV[2])

token = ARGV[2]

end



return token
$ redis-cli eval "$(cat stream_auth_token.lua)" 

1 
ssh-io:session:stream:auth:myuser 
86400 
"7292ed99-da44-42c3-897a-745b6e43ac33"

# => "7292ed99-da44-42c3-897a-745b6e43ac33"



$ redis-cli eval "$(cat stream_auth_token.lua)" 

1 
ssh-io:session:stream:auth:myuser 
86400 
"some-new-random-token"

# => "7292ed99-da44-42c3-897a-745b6e43ac33"
START
job "A"
I/O
stdin,
stdout, …
SSH
host "X"
SEND
queue "A:X"
LISTEN
queue “A:X”
AUTHORIZE
HTTP
SSE
Architecture
for SSH I/O
streaming
Thanks for listening
No Shiba Inus were harmed in the making of this presentation

More Related Content

What's hot

Tomáš Čorej - OpenSSH
Tomáš Čorej - OpenSSHTomáš Čorej - OpenSSH
Tomáš Čorej - OpenSSH
webelement
 
[1.2] Трюки при анализе защищенности веб приложений – продвинутая версия - С...
[1.2] Трюки при анализе защищенности веб приложений – продвинутая версия - С...[1.2] Трюки при анализе защищенности веб приложений – продвинутая версия - С...
[1.2] Трюки при анализе защищенности веб приложений – продвинутая версия - С...
OWASP Russia
 
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
CODE BLUE
 

What's hot (20)

Ssh cookbook
Ssh cookbookSsh cookbook
Ssh cookbook
 
Redis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your applicationRedis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your application
 
Tomáš Čorej - OpenSSH
Tomáš Čorej - OpenSSHTomáš Čorej - OpenSSH
Tomáš Čorej - OpenSSH
 
Yg byev2e
Yg byev2eYg byev2e
Yg byev2e
 
Web-servers & Application Hacking
Web-servers & Application HackingWeb-servers & Application Hacking
Web-servers & Application Hacking
 
Beyond Golden Containers: Complementing Docker with Puppet
Beyond Golden Containers: Complementing Docker with PuppetBeyond Golden Containers: Complementing Docker with Puppet
Beyond Golden Containers: Complementing Docker with Puppet
 
Summer of Fuzz: macOS
Summer of Fuzz: macOSSummer of Fuzz: macOS
Summer of Fuzz: macOS
 
PFIセミナー資料 H27.10.22
PFIセミナー資料 H27.10.22PFIセミナー資料 H27.10.22
PFIセミナー資料 H27.10.22
 
EuroPython 2016 : A Deep Dive into the Pymongo Driver
EuroPython 2016 : A Deep Dive into the Pymongo DriverEuroPython 2016 : A Deep Dive into the Pymongo Driver
EuroPython 2016 : A Deep Dive into the Pymongo Driver
 
Py conkr 20150829_docker-python
Py conkr 20150829_docker-pythonPy conkr 20150829_docker-python
Py conkr 20150829_docker-python
 
AWSをテラフォーミングする会(Terraformハンズオン)
AWSをテラフォーミングする会(Terraformハンズオン)AWSをテラフォーミングする会(Terraformハンズオン)
AWSをテラフォーミングする会(Terraformハンズオン)
 
OpenStack Swift - MSST 2011 Tutorial Day
OpenStack Swift - MSST 2011 Tutorial DayOpenStack Swift - MSST 2011 Tutorial Day
OpenStack Swift - MSST 2011 Tutorial Day
 
Ransomware for fun and non-profit
Ransomware for fun and non-profitRansomware for fun and non-profit
Ransomware for fun and non-profit
 
Malcon2017
Malcon2017Malcon2017
Malcon2017
 
Token based-oauth2
Token based-oauth2Token based-oauth2
Token based-oauth2
 
[1.2] Трюки при анализе защищенности веб приложений – продвинутая версия - С...
[1.2] Трюки при анализе защищенности веб приложений – продвинутая версия - С...[1.2] Трюки при анализе защищенности веб приложений – продвинутая версия - С...
[1.2] Трюки при анализе защищенности веб приложений – продвинутая версия - С...
 
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
 
wordpress with nginx on virtualization, jail
wordpress with nginx on virtualization, jailwordpress with nginx on virtualization, jail
wordpress with nginx on virtualization, jail
 
Fun with exploits old and new
Fun with exploits old and newFun with exploits old and new
Fun with exploits old and new
 
Scaling antispam solutions with Puppet
Scaling antispam solutions with PuppetScaling antispam solutions with Puppet
Scaling antispam solutions with Puppet
 

Viewers also liked

Viewers also liked (20)

The Redis API Akbar Ahmed, DynomiteDB
The Redis API Akbar Ahmed, DynomiteDBThe Redis API Akbar Ahmed, DynomiteDB
The Redis API Akbar Ahmed, DynomiteDB
 
Introduction to PEG
Introduction to PEGIntroduction to PEG
Introduction to PEG
 
Redis as a message queue
Redis as a message queueRedis as a message queue
Redis as a message queue
 
Architecture by Accident
Architecture by AccidentArchitecture by Accident
Architecture by Accident
 
nginx + lua + ObjectStorage ファイルアップロード/ダウンロードの高速化
nginx + lua + ObjectStorage  ファイルアップロード/ダウンロードの高速化nginx + lua + ObjectStorage  ファイルアップロード/ダウンロードの高速化
nginx + lua + ObjectStorage ファイルアップロード/ダウンロードの高速化
 
Redis Developers Day 2015 - Secondary Indexes and State of Lua
Redis Developers Day 2015 - Secondary Indexes and State of LuaRedis Developers Day 2015 - Secondary Indexes and State of Lua
Redis Developers Day 2015 - Secondary Indexes and State of Lua
 
Build a Geospatial App with Redis 3.2- Andrew Bass, Sean Yesmunt, Sergio Prad...
Build a Geospatial App with Redis 3.2- Andrew Bass, Sean Yesmunt, Sergio Prad...Build a Geospatial App with Redis 3.2- Andrew Bass, Sean Yesmunt, Sergio Prad...
Build a Geospatial App with Redis 3.2- Andrew Bass, Sean Yesmunt, Sergio Prad...
 
Use Redis in Odd and Unusual Ways
Use Redis in Odd and Unusual WaysUse Redis in Odd and Unusual Ways
Use Redis in Odd and Unusual Ways
 
Getting Started with Redis
Getting Started with RedisGetting Started with Redis
Getting Started with Redis
 
Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)
Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)
Get more than a cache back! The Microsoft Azure Redis Cache (NDC Oslo)
 
RespClient - Minimal Redis Client for PowerShell
RespClient - Minimal Redis Client for PowerShellRespClient - Minimal Redis Client for PowerShell
RespClient - Minimal Redis Client for PowerShell
 
UV logic using redis bitmap
UV logic using redis bitmapUV logic using redis bitmap
UV logic using redis bitmap
 
HIgh Performance Redis- Tague Griffith, GoPro
HIgh Performance Redis- Tague Griffith, GoProHIgh Performance Redis- Tague Griffith, GoPro
HIgh Performance Redis- Tague Griffith, GoPro
 
Celery: The Distributed Task Queue
Celery: The Distributed Task QueueCelery: The Distributed Task Queue
Celery: The Distributed Task Queue
 
Troubleshooting Redis- DaeMyung Kang, Kakao
Troubleshooting Redis- DaeMyung Kang, KakaoTroubleshooting Redis- DaeMyung Kang, Kakao
Troubleshooting Redis- DaeMyung Kang, Kakao
 
RedisConf 2016 talk - The Redis API: Simple, Composable, Powerful
RedisConf 2016 talk - The Redis API: Simple, Composable, PowerfulRedisConf 2016 talk - The Redis API: Simple, Composable, Powerful
RedisConf 2016 talk - The Redis API: Simple, Composable, Powerful
 
Using Redis as Distributed Cache for ASP.NET apps - Peter Kellner, 73rd Stre...
 Using Redis as Distributed Cache for ASP.NET apps - Peter Kellner, 73rd Stre... Using Redis as Distributed Cache for ASP.NET apps - Peter Kellner, 73rd Stre...
Using Redis as Distributed Cache for ASP.NET apps - Peter Kellner, 73rd Stre...
 
Scalable Streaming Data Pipelines with Redis
Scalable Streaming Data Pipelines with RedisScalable Streaming Data Pipelines with Redis
Scalable Streaming Data Pipelines with Redis
 
Cloud Foundry for Data Science
Cloud Foundry for Data ScienceCloud Foundry for Data Science
Cloud Foundry for Data Science
 
Redis & MongoDB: Stop Big Data Indigestion Before It Starts
Redis & MongoDB: Stop Big Data Indigestion Before It StartsRedis & MongoDB: Stop Big Data Indigestion Before It Starts
Redis & MongoDB: Stop Big Data Indigestion Before It Starts
 

Similar to SSH I/O Streaming via Redis-based Persistent Message Queue -Mani Tadayon

AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
clkao
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
Wesley Beary
 
Bh usa-01-kaminsky
Bh usa-01-kaminskyBh usa-01-kaminsky
Bh usa-01-kaminsky
Dan Kaminsky
 
WebSocketサーバを使ってみよう! Jul 2011
WebSocketサーバを使ってみよう! Jul 2011WebSocketサーバを使ってみよう! Jul 2011
WebSocketサーバを使ってみよう! Jul 2011
takanao ENODH
 

Similar to SSH I/O Streaming via Redis-based Persistent Message Queue -Mani Tadayon (20)

Nmap scripting engine
Nmap scripting engineNmap scripting engine
Nmap scripting engine
 
Running OpenStack + MidoNet (Using Orizuru)
Running OpenStack + MidoNet (Using Orizuru)Running OpenStack + MidoNet (Using Orizuru)
Running OpenStack + MidoNet (Using Orizuru)
 
Running OpenStack and Midonet - Nobuyuki Tamaoki, Virtual Tech Japan
Running OpenStack and Midonet - Nobuyuki Tamaoki, Virtual Tech JapanRunning OpenStack and Midonet - Nobuyuki Tamaoki, Virtual Tech Japan
Running OpenStack and Midonet - Nobuyuki Tamaoki, Virtual Tech Japan
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
Linux Network commands
Linux Network commandsLinux Network commands
Linux Network commands
 
Hopping in clouds - phpuk 17
Hopping in clouds - phpuk 17Hopping in clouds - phpuk 17
Hopping in clouds - phpuk 17
 
Puppet Camp 2012
Puppet Camp 2012Puppet Camp 2012
Puppet Camp 2012
 
2 docker engine_hands_on
2 docker engine_hands_on2 docker engine_hands_on
2 docker engine_hands_on
 
Mac OS X Lion で作る WordPress local 環境
Mac OS X Lion で作る WordPress local 環境Mac OS X Lion で作る WordPress local 環境
Mac OS X Lion で作る WordPress local 環境
 
BlueHat v17 || Detecting Compromise on Windows Endpoints with Osquery
BlueHat v17 || Detecting Compromise on Windows Endpoints with Osquery BlueHat v17 || Detecting Compromise on Windows Endpoints with Osquery
BlueHat v17 || Detecting Compromise on Windows Endpoints with Osquery
 
2009 cluster user training
2009 cluster user training2009 cluster user training
2009 cluster user training
 
Intro to SSH
Intro to SSHIntro to SSH
Intro to SSH
 
WebSocket - Nov 2011
WebSocket - Nov 2011WebSocket - Nov 2011
WebSocket - Nov 2011
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
 
14_526_topic10.ppt
14_526_topic10.ppt14_526_topic10.ppt
14_526_topic10.ppt
 
14_526_topic10.ppt
14_526_topic10.ppt14_526_topic10.ppt
14_526_topic10.ppt
 
14_526_topic10.ppt
14_526_topic10.ppt14_526_topic10.ppt
14_526_topic10.ppt
 
Bh usa-01-kaminsky
Bh usa-01-kaminskyBh usa-01-kaminsky
Bh usa-01-kaminsky
 
RenasCON 2023: Learning from honeypots
RenasCON 2023: Learning from honeypotsRenasCON 2023: Learning from honeypots
RenasCON 2023: Learning from honeypots
 
WebSocketサーバを使ってみよう! Jul 2011
WebSocketサーバを使ってみよう! Jul 2011WebSocketサーバを使ってみよう! Jul 2011
WebSocketサーバを使ってみよう! Jul 2011
 

More from Redis Labs

SQL, Redis and Kubernetes by Paul Stanton of Windocks - Redis Day Seattle 2020
SQL, Redis and Kubernetes by Paul Stanton of Windocks - Redis Day Seattle 2020SQL, Redis and Kubernetes by Paul Stanton of Windocks - Redis Day Seattle 2020
SQL, Redis and Kubernetes by Paul Stanton of Windocks - Redis Day Seattle 2020
Redis Labs
 
Anatomy of a Redis Command by Madelyn Olson of Amazon Web Services - Redis Da...
Anatomy of a Redis Command by Madelyn Olson of Amazon Web Services - Redis Da...Anatomy of a Redis Command by Madelyn Olson of Amazon Web Services - Redis Da...
Anatomy of a Redis Command by Madelyn Olson of Amazon Web Services - Redis Da...
Redis Labs
 
RediSearch 1.6 by Pieter Cailliau - Redis Day Bangalore 2020
RediSearch 1.6 by Pieter Cailliau - Redis Day Bangalore 2020RediSearch 1.6 by Pieter Cailliau - Redis Day Bangalore 2020
RediSearch 1.6 by Pieter Cailliau - Redis Day Bangalore 2020
Redis Labs
 
RedisGraph 2.0 by Pieter Cailliau - Redis Day Bangalore 2020
RedisGraph 2.0 by Pieter Cailliau - Redis Day Bangalore 2020RedisGraph 2.0 by Pieter Cailliau - Redis Day Bangalore 2020
RedisGraph 2.0 by Pieter Cailliau - Redis Day Bangalore 2020
Redis Labs
 

More from Redis Labs (20)

Redis Day Bangalore 2020 - Session state caching with redis
Redis Day Bangalore 2020 - Session state caching with redisRedis Day Bangalore 2020 - Session state caching with redis
Redis Day Bangalore 2020 - Session state caching with redis
 
Protecting Your API with Redis by Jane Paek - Redis Day Seattle 2020
Protecting Your API with Redis by Jane Paek - Redis Day Seattle 2020Protecting Your API with Redis by Jane Paek - Redis Day Seattle 2020
Protecting Your API with Redis by Jane Paek - Redis Day Seattle 2020
 
The Happy Marriage of Redis and Protobuf by Scott Haines of Twilio - Redis Da...
The Happy Marriage of Redis and Protobuf by Scott Haines of Twilio - Redis Da...The Happy Marriage of Redis and Protobuf by Scott Haines of Twilio - Redis Da...
The Happy Marriage of Redis and Protobuf by Scott Haines of Twilio - Redis Da...
 
SQL, Redis and Kubernetes by Paul Stanton of Windocks - Redis Day Seattle 2020
SQL, Redis and Kubernetes by Paul Stanton of Windocks - Redis Day Seattle 2020SQL, Redis and Kubernetes by Paul Stanton of Windocks - Redis Day Seattle 2020
SQL, Redis and Kubernetes by Paul Stanton of Windocks - Redis Day Seattle 2020
 
Rust and Redis - Solving Problems for Kubernetes by Ravi Jagannathan of VMwar...
Rust and Redis - Solving Problems for Kubernetes by Ravi Jagannathan of VMwar...Rust and Redis - Solving Problems for Kubernetes by Ravi Jagannathan of VMwar...
Rust and Redis - Solving Problems for Kubernetes by Ravi Jagannathan of VMwar...
 
Redis for Data Science and Engineering by Dmitry Polyakovsky of Oracle
Redis for Data Science and Engineering by Dmitry Polyakovsky of OracleRedis for Data Science and Engineering by Dmitry Polyakovsky of Oracle
Redis for Data Science and Engineering by Dmitry Polyakovsky of Oracle
 
Practical Use Cases for ACLs in Redis 6 by Jamie Scott - Redis Day Seattle 2020
Practical Use Cases for ACLs in Redis 6 by Jamie Scott - Redis Day Seattle 2020Practical Use Cases for ACLs in Redis 6 by Jamie Scott - Redis Day Seattle 2020
Practical Use Cases for ACLs in Redis 6 by Jamie Scott - Redis Day Seattle 2020
 
Moving Beyond Cache by Yiftach Shoolman Redis Labs - Redis Day Seattle 2020
Moving Beyond Cache by Yiftach Shoolman Redis Labs - Redis Day Seattle 2020Moving Beyond Cache by Yiftach Shoolman Redis Labs - Redis Day Seattle 2020
Moving Beyond Cache by Yiftach Shoolman Redis Labs - Redis Day Seattle 2020
 
Leveraging Redis for System Monitoring by Adam McCormick of SBG - Redis Day S...
Leveraging Redis for System Monitoring by Adam McCormick of SBG - Redis Day S...Leveraging Redis for System Monitoring by Adam McCormick of SBG - Redis Day S...
Leveraging Redis for System Monitoring by Adam McCormick of SBG - Redis Day S...
 
JSON in Redis - When to use RedisJSON by Jay Won of Coupang - Redis Day Seatt...
JSON in Redis - When to use RedisJSON by Jay Won of Coupang - Redis Day Seatt...JSON in Redis - When to use RedisJSON by Jay Won of Coupang - Redis Day Seatt...
JSON in Redis - When to use RedisJSON by Jay Won of Coupang - Redis Day Seatt...
 
Highly Available Persistent Session Management Service by Mohamed Elmergawi o...
Highly Available Persistent Session Management Service by Mohamed Elmergawi o...Highly Available Persistent Session Management Service by Mohamed Elmergawi o...
Highly Available Persistent Session Management Service by Mohamed Elmergawi o...
 
Anatomy of a Redis Command by Madelyn Olson of Amazon Web Services - Redis Da...
Anatomy of a Redis Command by Madelyn Olson of Amazon Web Services - Redis Da...Anatomy of a Redis Command by Madelyn Olson of Amazon Web Services - Redis Da...
Anatomy of a Redis Command by Madelyn Olson of Amazon Web Services - Redis Da...
 
Building a Multi-dimensional Analytics Engine with RedisGraph by Matthew Goos...
Building a Multi-dimensional Analytics Engine with RedisGraph by Matthew Goos...Building a Multi-dimensional Analytics Engine with RedisGraph by Matthew Goos...
Building a Multi-dimensional Analytics Engine with RedisGraph by Matthew Goos...
 
RediSearch 1.6 by Pieter Cailliau - Redis Day Bangalore 2020
RediSearch 1.6 by Pieter Cailliau - Redis Day Bangalore 2020RediSearch 1.6 by Pieter Cailliau - Redis Day Bangalore 2020
RediSearch 1.6 by Pieter Cailliau - Redis Day Bangalore 2020
 
RedisGraph 2.0 by Pieter Cailliau - Redis Day Bangalore 2020
RedisGraph 2.0 by Pieter Cailliau - Redis Day Bangalore 2020RedisGraph 2.0 by Pieter Cailliau - Redis Day Bangalore 2020
RedisGraph 2.0 by Pieter Cailliau - Redis Day Bangalore 2020
 
RedisTimeSeries 1.2 by Pieter Cailliau - Redis Day Bangalore 2020
RedisTimeSeries 1.2 by Pieter Cailliau - Redis Day Bangalore 2020RedisTimeSeries 1.2 by Pieter Cailliau - Redis Day Bangalore 2020
RedisTimeSeries 1.2 by Pieter Cailliau - Redis Day Bangalore 2020
 
RedisAI 0.9 by Sherin Thomas of Tensorwerk - Redis Day Bangalore 2020
RedisAI 0.9 by Sherin Thomas of Tensorwerk - Redis Day Bangalore 2020RedisAI 0.9 by Sherin Thomas of Tensorwerk - Redis Day Bangalore 2020
RedisAI 0.9 by Sherin Thomas of Tensorwerk - Redis Day Bangalore 2020
 
Rate-Limiting 30 Million requests by Vijay Lakshminarayanan and Girish Koundi...
Rate-Limiting 30 Million requests by Vijay Lakshminarayanan and Girish Koundi...Rate-Limiting 30 Million requests by Vijay Lakshminarayanan and Girish Koundi...
Rate-Limiting 30 Million requests by Vijay Lakshminarayanan and Girish Koundi...
 
Three Pillars of Observability by Rajalakshmi Raji Srinivasan of Site24x7 Zoh...
Three Pillars of Observability by Rajalakshmi Raji Srinivasan of Site24x7 Zoh...Three Pillars of Observability by Rajalakshmi Raji Srinivasan of Site24x7 Zoh...
Three Pillars of Observability by Rajalakshmi Raji Srinivasan of Site24x7 Zoh...
 
Solving Complex Scaling Problems by Prashant Kumar and Abhishek Jain of Myntr...
Solving Complex Scaling Problems by Prashant Kumar and Abhishek Jain of Myntr...Solving Complex Scaling Problems by Prashant Kumar and Abhishek Jain of Myntr...
Solving Complex Scaling Problems by Prashant Kumar and Abhishek Jain of Myntr...
 

Recently uploaded

Recently uploaded (20)

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 

SSH I/O Streaming via Redis-based Persistent Message Queue -Mani Tadayon

  • 1.
  • 2. START job "A" I/O stdin, stdout, … SSH session "X" SEND queue "A:X" LISTEN queue "X:A" AUTHORIZE HTTP SSE Architecture for SSH I/O streaming SSH I/O streaming via Redis-based persistent message queue Mani Tadayon RedisConf 2016
  • 3. About me • @bwsr_sr • Working in software since ’01 • Using Redis since ’13 <shameless-plug> • Just finished a book on Ruby testing: RSpec Essentials • http://amzn.com/1784395900 </shameless-plug>
  • 4. How to build a message queue with Redis • Live listener > subscribe mychannel • Publisher > publish mychannel mymessage And that’s my talk, thanks for listening! DoDo’s mad!
  • 5. – http://antirez.com/news/88 “Redis apparently is at the same time the best and the worst system to use like that.”
  • 7.
  • 8.
  • 9. START job "A" I/O stdin, stdout, … SSH host "X" SEND queue "A:X" LISTEN queue “A:X” AUTHORIZE HTTP SSE Architecture for SSH I/O streaming
  • 10. How to build a persistent message queue with Redis • Retrieve persisted messages > lrange mykey 0 -1 • Publisher > rpush mykey mymessage What about a live listener?
  • 11. The best of both worlds • Live listener > subscribe mychannel • Retrieve persisted messages > lrange mykey 0 -1 • Publisher > rpush mykey mymessage > publish mychannel mymessage That’s pretty much it. But the SSH I/O feature needs a few more features.
  • 12. • Lookup by session ID (“A:X”) • Use a simple list of key names > rpush byjob mykey > expire byjob 604800 • Lookup by hostname (“A:*”) • Use a zset with timestamp as score > zadd byhost 1463012431 mykey > zremrangebyscore byhost 0 1462407631
  • 13. • Wrap each message in a transaction • Protect against excessive memory usage (150GB in 2 hours on the 1st day…) • Limit number of persisted messages per job • Expire persisted messages (more aggressively for verbose jobs) • Stop sending messages above a threshold (handled outside Redis) > multi > rpush mykey mymessage > expire mykey 604800 > ltrim mykey -100 -1 > publish mychannel mymessage > exec
  • 14. • Set up indexes for lookup (only once per job) > rpush byjob mykey > expire byjob 604800 > zadd byhost 1463012431 mykey > zremrangebyscore byhost 0 1462407631
  • 15. Key and channel names ssh-io:session:event:persisted:$ID:$FQDN ssh-io:session:event:live:$ID:$FQDN ssh-io:session:event_lookup:by_job:$ID ssh-io:session:event_lookup:by_hostname:$FQDN
  • 16. > multi > rpush ssh-io:session:event:persisted:b8042948:fakehost.example.com {"session_started":"About to run 4 commands on fakehost.example.com for CustomScript- TestStreamingSimple:b8042948","io_type":"session_started","timestamp":1462407631} > expire ssh-io:session:event:persisted:b8042948:fakehost.example.com 604800 > ltrim ssh-io:session:event:persisted:b8042948:fakehost.example.com -100 -1 > publish ssh-io:session:event:live:b8042948:fakehost.example.com {"session_started":"About to run 4 commands on fakehost.example.com for CustomScript- TestStreamingSimple:b8042948","io_type":"session_started","timestamp":1462407631} > exec > rpush ssh-io:session:event_lookup:by_job:b8042948 ssh- io:session:event:persisted:b8042948:fakehost.example.com > expire ssh-io:session:event_lookup:by_job:b8042948 604800 > zadd ssh-io:session:event_lookup:by_hostname:fakehost.example.com 1463012431 ssh- io:session:event:persisted:b8042948:fakehost.example.com > zremrangebyscore ssh-io:session:event_lookup:by_hostname:fakehost.example.com 0 1462407631
  • 17. > multi > rpush ssh-io:session:event:persisted:b8042948:fakehost.example.com {"username":"deploy","stdin":"echo "ping number 1"","hostname":"fakehost.example.com","io_type":"stdin","timestamp":1462407631} > expire ssh-io:session:event:persisted:b8042948:fakehost.example.com 604800 > ltrim ssh-io:session:event:persisted:b8042948:fakehost.example.com -100 -1 > publish ssh-io:session:event:live:b8042948:fakehost.example.com {"username":"deploy","stdin":"echo "ping number 1"","hostname":"fakehost.example.com","io_type":"stdin","timestamp":1462407631} > exec # … multi,rpush,expire,ltrim,publish,exec … > multi > rpush ssh-io:session:event:persisted:b8042948:fakehost.example.com {"session_finished":"Ran 4 of 4 commands on fakehost.example.com for CustomScript- TestStreamingSimple:b8042948","success":false,"io_type":"session_finished","timestamp": 1462407631} > expire ssh-io:session:event:persisted:b8042948:fakehost.example.com 604800 > ltrim ssh-io:session:event:persisted:b8042948:fakehost.example.com -100 -1 > publish ssh-io:session:event:live:b8042948:fakehost.example.com {"session_finished":"Ran 4 of 4 commands on fakehost.example.com for CustomScript- TestStreamingSimple:b8042948","success":false,"io_type":"session_finished","timestamp": 1462407631}
  • 18. Lookup by hostname • Lua script that uses the zset index • Returns all events, in order, per hostname
  • 19. $ redis-cli zrange ssh-io:session:event_lookup:by_hostname:fakehost.example.com 0 -1
 1) "ssh-io:session:event:persisted:0bd6005b-1999-42ab-9b54-2585e0383bcb:fakehost.example.com"
 2) "ssh-io:session:event:persisted:84ae935f-55a2-4210-a356-87a0da7c3b58:fakehost.example.com"
 3) "ssh-io:session:event:persisted:35696242-a59d-4a1f-b36f-4ee988b558c5:fakehost.example.com"
 4) "ssh-io:session:event:persisted:b72488ec-816c-48b9-a48d-ab31cbc41802:fakehost.example.com"
 5) "ssh-io:session:event:persisted:5b13b4bd-2800-47fe-a821-a548c90054b6:fakehost.example.com"
 6) "ssh-io:session:event:persisted:26078a92-e349-43a7-9375-d0ce511b1dbd:fakehost.example.com"
 7) "ssh-io:session:event:persisted:4c3f31f0-dd2d-411f-bfbe-d6591698bf3a:fakehost.example.com"
 8) "ssh-io:session:event:persisted:60983166-f580-44d6-9058-3b8bb04c1441:fakehost.example.com"
 9) "ssh-io:session:event:persisted:572de4a5-3d15-4160-ab42-006407662ca8:fakehost.example.com"
 10) "ssh-io:session:event:persisted:3b405df9-3618-4cc2-b245-4dac4b7a203b:fakehost.example.com"
 11) "ssh-io:session:event:persisted:5968f887-9228-4963-9515-b92eda944063:fakehost.example.com"
 12) "ssh-io:session:event:persisted:ebcd6068-4a22-48f1-a333-36a312bb78f0:fakehost.example.com"
 13) "ssh-io:session:event:persisted:d22ae42d-4343-46b8-a477-8fa057bc34b5:fakehost.example.com"
 14) "ssh-io:session:event:persisted:49c994db-9d3d-4453-ac83-8dbf038a655d:fakehost.example.com"
 15) "ssh-io:session:event:persisted:2fc5ea10-c8f8-42e7-93d4-073b68826ffa:fakehost.example.com"
 16) "ssh-io:session:event:persisted:b8042948-63f1-4c6f-afc8-8d2384b3b155:fakehost.example.com"
 17) "ssh-io:session:event:persisted:5fee9662-af66-4027-9963-ff59716dc7e0:fakehost.example.com"
 18) "ssh-io:session:event:persisted:c919f801-ab8b-4f31-92f8-3f51d6b7b7dc:fakehost.example.com"
 19) "ssh-io:session:event:persisted:22f480d9-31cb-4054-9861-51d0275c9468:fakehost.example.com"
 20) "ssh-io:session:event:persisted:7710e61f-921c-4d6d-bbf4-e9c35d932f1a:fakehost.example.com"
  • 20. -- finds the keys for all sessions for... 
 -- ...a given hostname using lookup lists,
 -- then retrieve all events in all keys
 -- use nested numeric lua tables (i.e. arrays)...
 -- ...since redis will wipe out string keys
 -- see: http://redis.io/commands/eval 
 -- (Conversion between Lua and Redis data types) 
 local keys = redis.call("zrange", KEYS[1], 0, -1)
 local returner = {}
 for i, key in ipairs(keys) do
 returner[i] = {
 key,
 redis.call("lrange", key, 0, -1)
 }
 end
 return returner

  • 21. $ redis-cli eval "$(cat values-from-lookup-set.lua)" 
 1 ssh-io:session:event_lookup:by_hostname:fakehost.example.com
 
 1) 1) "ssh-io:session:event:persisted: 0bd6005b-1999-42ab-9b54-2585e0383bcb:fakehost.example.com"
 2) 1) "{"session_started":"About to run 4 commands on fakehost.example.com for :0bd6005b-1999-42ab-9b54-2585e0383bcb","io_type": "session_started","timestamp":1462405267}"
 
 # … 18 more sessions …
 
 20) 1) "ssh-io:session:event:persisted:7710e61f-921c-4d6d-bbf4- e9c35d932f1a:fakehost.example.com"
 2) 1) "{"session_started":"About to run 6 commands on fakehost.example.com for CustomScript-TestStreamingSimple:7710e61f-921c-4d6d- bbf4-e9c35d932f1a","io_type":"session_started","timestamp":1462524784}"
  • 22. Authentication • From browser directly to node.js web service • Web app creates an auth token • Token written to Redis… • …and stored in browser session • 1 day expiry • Simple Lua script to create or retrieve token
  • 23. local token = ''
 
 if redis.call('exists', KEYS[1]) == 1 then
 token = redis.call('get', KEYS[1])
 else
 redis.call('setex', KEYS[1], ARGV[1], ARGV[2])
 token = ARGV[2]
 end
 
 return token
  • 24. $ redis-cli eval "$(cat stream_auth_token.lua)" 
 1 ssh-io:session:stream:auth:myuser 86400 "7292ed99-da44-42c3-897a-745b6e43ac33"
 # => "7292ed99-da44-42c3-897a-745b6e43ac33"
 
 $ redis-cli eval "$(cat stream_auth_token.lua)" 
 1 ssh-io:session:stream:auth:myuser 86400 "some-new-random-token"
 # => "7292ed99-da44-42c3-897a-745b6e43ac33"
  • 25. START job "A" I/O stdin, stdout, … SSH host "X" SEND queue "A:X" LISTEN queue “A:X” AUTHORIZE HTTP SSE Architecture for SSH I/O streaming
  • 26. Thanks for listening No Shiba Inus were harmed in the making of this presentation