Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Redis Hacks
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
David Cramer
May 03, 2014
Technology
280
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Redis Hacks
Python Nordeste 2014 - Lightning Talk
David Cramer
May 03, 2014
More Decks by David Cramer
See All by David Cramer
Mastering Duct Tape (PyCon Balkan 2018)
zeeg
2
930
Open Source as a Business (PyCon SG 2014)
zeeg
0
420
Angular.js Workshop (PyCon SG 2014)
zeeg
0
280
Architecting a Culture of Quality
zeeg
2
350
Release Faster
zeeg
12
1.5k
Open Source as a Business (EuroPython 2013)
zeeg
18
17k
Building to Scale (PyCon TW 2013)
zeeg
18
1.4k
Building to Scale
zeeg
28
24k
Lessons in Testing - DjangoCon 2012
zeeg
8
1.5k
Other Decks in Technology
See All in Technology
行動するAIのためのオントロジー | DevRev — Encraft #26.pdf
dvrv_tknrszk
2
630
ログラスのマルチプロダクトを 支える認証基盤 〜テナントごとに異なる統制とどう向き合うか〜
dada4386
3
280
企業の現実世界をグラフで写し取る
sansantech
PRO
0
220
顧客の成果創出とプロダクトの成長を 両立するためのFDE
sansantech
PRO
0
530
「大丈夫そう?」をObservabilityで確かめる
mrmtsu
0
240
VS Code × GitHub Copilot での Fabric 開発
ryomaru0825
1
200
spanner-autoscalerに学ぶ CRD設計パターン 〜自動化と緊急時対応を両立する Kubernetesコントローラーの作り方〜
tkuchiki
0
210
いちAWSエンジニアのAI活用を振り返る #devio2026 / devio osaka 2026 kawahara
masahirokawahara
1
290
20260930_Gemma4_Hands-on
tsho
0
180
ボードゲームの遊び相手をFoundation Modelsで作る / iOSDC Japan 2026
genda
0
240
DORA_Metrics.pdf
wagnerfusca
1
140
プラットフォームを「作る」、 チームに「入り込む」
sansantech
PRO
0
410
Featured
See All Featured
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
620
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
600
Building Flexible Design Systems
yeseniaperezcruz
330
41k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
The untapped power of vector embeddings
frankvandijk
2
1.9k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
390
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
350
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
580
[RailsConf 2023] Rails as a piece of cake
palkan
59
7k
Transcript
David Cramer twitter.com/zeeg Redis Hacks (or “How Sentry Scales”)
Buffering Writes
r = Redis() ! def incr(type, id): key = 'pending:{}'.format(type)
! r.zincrby(key, id, 1)
r = Redis() ! def flush(type): key = 'pending:{}'.format(type) result
= r.zrange(key, 0, -1, withscores=True) ! for id, count in result: prms = {'type': type, 'count': count, 'id': id} ! sql(""" update %(type)s set count = count + % (count)d where id = %(id)s """, prms)
Rate Limiting
r = Redis() ! def process_hit(project_id): epoch = time() /
60 key = ‘{}:{}’.format(project_id, epoch) ! pipe = r.pipeline() pipe.incr(key) pipe.expire(key, 60) result = pipe.execute() ! # return current value return int(result[0])
def request(project_id): result = process_hit(project_id) if result > 20: return
Response(status=429) return Response(status=200)
Time Series Data
def count_hits_today(project_id): start = time() end = now + DAY_SECONDS
! pipe = r.pipeline() for epoch in xrange(now, end, 10): key = ‘{}:{}’.format( project_id, epoch) pipe.get(key) results = pipe.execute() ! # remove non-zero results results = filter(bool, results) # coerce remainder to ints results = map(int, results) # return sum of buckets return sum(results)
Good-enough Locks
from contextlib import contextmanager ! r = Redis() ! @contextmanager
def lock(key, nowait=True): while not r.setnx(key, '1'): if nowait: raise Locked('try again soon!') sleep(0.01) ! # limit lock time to 10 seconds r.expire(key, 10) ! # do something crazy yield ! # explicitly unlock r.delete(key)
def do_something_crazy(): with lock('crazy'): print 'Hello World!'
Basic Sharding via Nydus
from nydus.db import create_cluster ! redis = create_cluster({ 'backend': 'nydus.db.backends.redis.Redis',
'hosts': { 0: {'db': 0}, 1: {'db': 1}, }, 'router': 'nydus.db.routers.keyvalue.PartitionRouter', })
def count_hits_today(project_id): start = time() end = now + DAY_SECONDS
! keys = [] for epoch in xrange(now, end, 10): key = '{}:{}'.format(project_id, epoch) keys.append(key) ! with redis.map() as conn: results = map(conn.get, keys) ! # remove non-zero results results = filter(bool, results) # coerce remainder to ints results = map(int, results) # return sum of buckets return sum(results)