SlideShare a Scribd company logo
1 of 23
Download to read offline
Distributed locks
KnapsackPro.com API case study
Artur Trzop
Start with a problem
But know the first
CircleCI container
Execute Rspec tests
Run all tests in single container
First container
Execute Rspec tests
Second container
Execute Rspec tests
Split tests between container
CI build for git commit
First container
Execute Rspec
tests fetched from work queue
Second container
Execute Rspec
tests fetched from work queue
Dynamic tests split between container
with knapsack_pro gem
Tests in work queue on
KnapsackPro.com API server
First requests from any container
should create a new work queue
for the git commit
def test_files
create_queue unless queue_exists?
test_files_from_top_of_the_queue
end
When this code can happen
at the same time?
● development - webrick is single threaded (bug won’t happen)
● Production (bug happens):
○ unicorn (multiple processes)
○ puma (multiple threads and/or multiple processes)
What is distributed lock?
synchronize access to shared resources
It means different processes must operate with shared resources
in a mutually exclusive way
Why you want a lock in a
distributed application?
● Efficiency
○ Avoid expensive computation
○ Saves time & money
Why you want a lock in a
distributed application?
● Correctness
○ Prevent corrupted data
○ Prevent data loss
○ Prevent data inconsistency
What tool I could use?
https://github.com/dv/redis-semaphore
How I solve the problem?
● Write tests to do concurrent requests against staging
○ Requests in separate threads
● Verify if the problem exists after implementing fix
Implementation fix
def test_files
semaphore = Redis::Semaphore.new(:semaphore_for_ci_build_id, host: "localhost")
semaphore.lock(5) do
create_queue unless queue_exists?
end
test_files_from_top_of_the_queue
end
What should I remember
● Locks are hard
● Distributed locks are even harder
● Don't reinvent the wheel, use proven solutions
● Most web apps are not thread-safe due to missing locks.
○ Expect edge cases while you grow.
Another example
def save
build = find_build || new_build
do_something_complex_with_build
build.save
end
With distributed lock
def save
semaphore.lock(5) do
build = find_build || new_build
do_something_complex_with_build
build.save
end
end
What distributed lock
allows us?
● When single redis DB
○ You can have multiple unicorn/puma processes
○ You can have multiple machines if each use the same redis DB
What distributed lock
allows us?
● When multiple redis DBs
○ Use library that supports Redlock algorithm
■ redlock-rb gem
■ https://redis.io/topics/distlock
● Is Redlock perfect? Kind of, because it has timing assumptions.
https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html
Response from Redis author http://antirez.com/news/101
Tips
● Be aware of trade-off. Do you care about efficiency or correctness?
● Test your endpoints with concurrent requests to reproduce problem
● Use transactions when changing many records
● Use unique index to ensure data consistency in DB
● Use tested distribution lock solutions
Nice to read
https://makandracards.com/makandra/31937-differences-between-transactions-an
d-locking
Thanks
Distributed locks in Ruby - Correctness vs Efficiency - Knapsack Pro case study (mutex, semaphore)

More Related Content

What's hot

Developing Rich Internet Applications with Perl and JavaScript
Developing Rich Internet Applications with Perl and JavaScriptDeveloping Rich Internet Applications with Perl and JavaScript
Developing Rich Internet Applications with Perl and JavaScript
nohuhu
 
CTU June 2011 - C# 5.0 - ASYNC & Await
CTU June 2011 - C# 5.0 - ASYNC & AwaitCTU June 2011 - C# 5.0 - ASYNC & Await
CTU June 2011 - C# 5.0 - ASYNC & Await
Spiffy
 

What's hot (20)

Developing Rich Internet Applications with Perl and JavaScript
Developing Rich Internet Applications with Perl and JavaScriptDeveloping Rich Internet Applications with Perl and JavaScript
Developing Rich Internet Applications with Perl and JavaScript
 
Ruby eventmachine pres at rubybdx
Ruby eventmachine pres at rubybdxRuby eventmachine pres at rubybdx
Ruby eventmachine pres at rubybdx
 
Git+jenkins+rex presentation
Git+jenkins+rex presentationGit+jenkins+rex presentation
Git+jenkins+rex presentation
 
BBC's GraphDB (formerly Owlim) AWS Cloud Migration
BBC's GraphDB (formerly Owlim) AWS Cloud MigrationBBC's GraphDB (formerly Owlim) AWS Cloud Migration
BBC's GraphDB (formerly Owlim) AWS Cloud Migration
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Build a chatroom!
Build a chatroom!Build a chatroom!
Build a chatroom!
 
Add a backend and deploy!
Add a backend and deploy!Add a backend and deploy!
Add a backend and deploy!
 
Are you using an opensource library? There's a good chance you are vulnerable...
Are you using an opensource library? There's a good chance you are vulnerable...Are you using an opensource library? There's a good chance you are vulnerable...
Are you using an opensource library? There's a good chance you are vulnerable...
 
RSYSLOG v8 improvements and how to write plugins in any language.
RSYSLOG v8 improvements and how to write plugins in any language.RSYSLOG v8 improvements and how to write plugins in any language.
RSYSLOG v8 improvements and how to write plugins in any language.
 
CTU June 2011 - C# 5.0 - ASYNC & Await
CTU June 2011 - C# 5.0 - ASYNC & AwaitCTU June 2011 - C# 5.0 - ASYNC & Await
CTU June 2011 - C# 5.0 - ASYNC & Await
 
TDD for joomla extensions
TDD for joomla extensionsTDD for joomla extensions
TDD for joomla extensions
 
openSUSE Conference 2017 - The Docker at Travis Presentation
openSUSE Conference 2017 - The Docker at Travis PresentationopenSUSE Conference 2017 - The Docker at Travis Presentation
openSUSE Conference 2017 - The Docker at Travis Presentation
 
grifork - fast propagative task runner -
grifork - fast propagative task runner -grifork - fast propagative task runner -
grifork - fast propagative task runner -
 
Intro to Node.js
Intro to Node.jsIntro to Node.js
Intro to Node.js
 
Rust Programming Language
Rust Programming LanguageRust Programming Language
Rust Programming Language
 
Running of nist test
Running of nist testRunning of nist test
Running of nist test
 
"fireap" - fast task runner on consul
"fireap" - fast task runner on consul"fireap" - fast task runner on consul
"fireap" - fast task runner on consul
 
Deep drive into rust programming language
Deep drive into rust programming languageDeep drive into rust programming language
Deep drive into rust programming language
 
DevOps in realtime
DevOps in realtimeDevOps in realtime
DevOps in realtime
 
ruby + websocket + haproxy
ruby + websocket + haproxyruby + websocket + haproxy
ruby + websocket + haproxy
 

Similar to Distributed locks in Ruby - Correctness vs Efficiency - Knapsack Pro case study (mutex, semaphore)

Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx PluginGr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
Yasuharu Nakano
 
Hashicorp-Terraform-Deep-Dive-with-no-Fear-Victor-Turbinsky-Texuna.pdf
Hashicorp-Terraform-Deep-Dive-with-no-Fear-Victor-Turbinsky-Texuna.pdfHashicorp-Terraform-Deep-Dive-with-no-Fear-Victor-Turbinsky-Texuna.pdf
Hashicorp-Terraform-Deep-Dive-with-no-Fear-Victor-Turbinsky-Texuna.pdf
ssuser705051
 

Similar to Distributed locks in Ruby - Correctness vs Efficiency - Knapsack Pro case study (mutex, semaphore) (20)

Parallelizing CI using Docker Swarm-Mode
Parallelizing CI using Docker Swarm-ModeParallelizing CI using Docker Swarm-Mode
Parallelizing CI using Docker Swarm-Mode
 
Introduction to containers
Introduction to containersIntroduction to containers
Introduction to containers
 
Deploying to DigitalOcean With GitHub Actions
Deploying to DigitalOcean With GitHub ActionsDeploying to DigitalOcean With GitHub Actions
Deploying to DigitalOcean With GitHub Actions
 
Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx PluginGr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
 
Distributed Elixir
Distributed ElixirDistributed Elixir
Distributed Elixir
 
Containers: from development to production at DevNation 2015
Containers: from development to production at DevNation 2015Containers: from development to production at DevNation 2015
Containers: from development to production at DevNation 2015
 
MERIMeeting du 27 mai 2014 - Parallel Programming
MERIMeeting du 27 mai 2014 - Parallel ProgrammingMERIMeeting du 27 mai 2014 - Parallel Programming
MERIMeeting du 27 mai 2014 - Parallel Programming
 
Hands-on Lab: Red Hat Container Development & OpenShift
Hands-on Lab: Red Hat Container Development & OpenShiftHands-on Lab: Red Hat Container Development & OpenShift
Hands-on Lab: Red Hat Container Development & OpenShift
 
Let's Talk Locks!
Let's Talk Locks!Let's Talk Locks!
Let's Talk Locks!
 
Mono Repo
Mono RepoMono Repo
Mono Repo
 
StorageOS, Storage for Containers Shouldn't Be Annoying at Container Camp UK
StorageOS, Storage for Containers Shouldn't Be Annoying at Container Camp UKStorageOS, Storage for Containers Shouldn't Be Annoying at Container Camp UK
StorageOS, Storage for Containers Shouldn't Be Annoying at Container Camp UK
 
Hashicorp-Terraform-Deep-Dive-with-no-Fear-Victor-Turbinsky-Texuna.pdf
Hashicorp-Terraform-Deep-Dive-with-no-Fear-Victor-Turbinsky-Texuna.pdfHashicorp-Terraform-Deep-Dive-with-no-Fear-Victor-Turbinsky-Texuna.pdf
Hashicorp-Terraform-Deep-Dive-with-no-Fear-Victor-Turbinsky-Texuna.pdf
 
Terraform-2.pdf
Terraform-2.pdfTerraform-2.pdf
Terraform-2.pdf
 
Build optimization mechanisms in GitLab and Docker
Build optimization mechanisms in GitLab and DockerBuild optimization mechanisms in GitLab and Docker
Build optimization mechanisms in GitLab and Docker
 
Codeception: introduction to php testing (v2 - Aberdeen php)
Codeception: introduction to php testing (v2 - Aberdeen php)Codeception: introduction to php testing (v2 - Aberdeen php)
Codeception: introduction to php testing (v2 - Aberdeen php)
 
Demo 0.9.4
Demo 0.9.4Demo 0.9.4
Demo 0.9.4
 
It's always sunny with OpenJ9
It's always sunny with OpenJ9It's always sunny with OpenJ9
It's always sunny with OpenJ9
 
Docker 102 - Immutable Infrastructure
Docker 102 - Immutable InfrastructureDocker 102 - Immutable Infrastructure
Docker 102 - Immutable Infrastructure
 
The State of the Veil Framework
The State of the Veil FrameworkThe State of the Veil Framework
The State of the Veil Framework
 
Software Testing
Software TestingSoftware Testing
Software Testing
 

Recently uploaded

Recently uploaded (20)

EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
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...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
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...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
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...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
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
 
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
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 

Distributed locks in Ruby - Correctness vs Efficiency - Knapsack Pro case study (mutex, semaphore)

  • 1. Distributed locks KnapsackPro.com API case study Artur Trzop
  • 2. Start with a problem
  • 3. But know the first
  • 4. CircleCI container Execute Rspec tests Run all tests in single container
  • 5. First container Execute Rspec tests Second container Execute Rspec tests Split tests between container CI build for git commit
  • 6. First container Execute Rspec tests fetched from work queue Second container Execute Rspec tests fetched from work queue Dynamic tests split between container with knapsack_pro gem Tests in work queue on KnapsackPro.com API server
  • 7. First requests from any container should create a new work queue for the git commit def test_files create_queue unless queue_exists? test_files_from_top_of_the_queue end
  • 8. When this code can happen at the same time? ● development - webrick is single threaded (bug won’t happen) ● Production (bug happens): ○ unicorn (multiple processes) ○ puma (multiple threads and/or multiple processes)
  • 9. What is distributed lock? synchronize access to shared resources It means different processes must operate with shared resources in a mutually exclusive way
  • 10. Why you want a lock in a distributed application? ● Efficiency ○ Avoid expensive computation ○ Saves time & money
  • 11. Why you want a lock in a distributed application? ● Correctness ○ Prevent corrupted data ○ Prevent data loss ○ Prevent data inconsistency
  • 12. What tool I could use? https://github.com/dv/redis-semaphore
  • 13. How I solve the problem? ● Write tests to do concurrent requests against staging ○ Requests in separate threads ● Verify if the problem exists after implementing fix
  • 14. Implementation fix def test_files semaphore = Redis::Semaphore.new(:semaphore_for_ci_build_id, host: "localhost") semaphore.lock(5) do create_queue unless queue_exists? end test_files_from_top_of_the_queue end
  • 15. What should I remember ● Locks are hard ● Distributed locks are even harder ● Don't reinvent the wheel, use proven solutions ● Most web apps are not thread-safe due to missing locks. ○ Expect edge cases while you grow.
  • 16. Another example def save build = find_build || new_build do_something_complex_with_build build.save end
  • 17. With distributed lock def save semaphore.lock(5) do build = find_build || new_build do_something_complex_with_build build.save end end
  • 18. What distributed lock allows us? ● When single redis DB ○ You can have multiple unicorn/puma processes ○ You can have multiple machines if each use the same redis DB
  • 19. What distributed lock allows us? ● When multiple redis DBs ○ Use library that supports Redlock algorithm ■ redlock-rb gem ■ https://redis.io/topics/distlock ● Is Redlock perfect? Kind of, because it has timing assumptions. https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html Response from Redis author http://antirez.com/news/101
  • 20. Tips ● Be aware of trade-off. Do you care about efficiency or correctness? ● Test your endpoints with concurrent requests to reproduce problem ● Use transactions when changing many records ● Use unique index to ensure data consistency in DB ● Use tested distribution lock solutions