Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Redis Hacks
Search
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
V8コントリビュート超入門
riyaamemiya
0
150
スクラムで身についていた動き方を、XPで捉え直してみた
codmoninc
PRO
1
310
AI活用の現在地、 ちゃんと見えてますか?/XPfest-2026
visional_engineering_and_design
0
160
Bet AI Day 2026丨AIを「使う」から、AIが「働く」へ ― LayerXが進める「組織AI」の社会実装
layerx
PRO
3
2.8k
推論の観測、できていますか? 〜 Google Cloud Gemini Enterprise Agent Platformで 3つの Gemini モデルを実測して踏んだ、評価の罠 〜
shukob
PRO
0
180
Adaptive Warehouse を今すぐ導入すべき理由と迷ったときの判断基準
__allllllllez__
0
110
コスト最適化の「めんどくさい」を AWS FinOps Agent でチョット楽にする
classmethod_kaz
0
270
Autonomous AI Databaseサービス・アップデート(FY27)/ adb-service-update-jp-fy27
oracle4engineer
PRO
0
130
OpenTelemetry eBPF Instrumentationの舞台裏 / Behind the Scenes of OpenTelemetry eBPF Instrumentation
ymotongpoo
1
250
DGX Sparkを2台使って いろいろ動かす話
sonoda_mj
1
140
Snowflakeで実現する全社横断の顧客の声(VOC)分析・活用基盤@Snowflake World Tour Tokyo 2026
yuto16
0
100
多層防御と最⼩権限で実現する、安全なAIエージェント設計パターン
lycorptech_jp
PRO
1
210
Featured
See All Featured
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
200
Designing for Performance
lara
611
70k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
340
Tell your own story through comics
letsgokoyo
1
1.1k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Chasing Engaging Ingredients in Design
codingconduct
0
300
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
GitHub's CSS Performance
jonrohan
1033
470k
The Pragmatic Product Professional
lauravandoore
37
7.4k
Rails Girls Zürich Keynote
gr2m
96
14k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
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)