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
3
250
Redis Hacks
Python Nordeste 2014 - Lightning Talk
David Cramer
May 03, 2014
Tweet
Share
More Decks by David Cramer
See All by David Cramer
Mastering Duct Tape (PyCon Balkan 2018)
zeeg
2
890
Open Source as a Business (PyCon SG 2014)
zeeg
0
390
Angular.js Workshop (PyCon SG 2014)
zeeg
0
260
Architecting a Culture of Quality
zeeg
2
320
Release Faster
zeeg
12
1.4k
Open Source as a Business (EuroPython 2013)
zeeg
18
17k
Building to Scale (PyCon TW 2013)
zeeg
18
1.3k
Building to Scale
zeeg
28
24k
Lessons in Testing - DjangoCon 2012
zeeg
8
1.4k
Other Decks in Technology
See All in Technology
今すぐGoogle Antigravityを触りましょう
rfdnxbro
0
220
The Complete Android UI Testing Landscape: From Journey to Traditional Approaches
alexzhukovich
1
120
『ソフトウェア』で『リアル』を動かす:クレーンゲームからデータ基盤までの統一アーキテクチャ / アーキテクチャConference 2025
genda
0
1.4k
TypeScript 6.0で非推奨化されるオプションたち
uhyo
15
5.5k
Data Hubグループ 紹介資料
sansan33
PRO
0
2.3k
信頼性が求められる業務のAIAgentのアーキテクチャ設計の勘所と課題
miyatakoji
0
190
.NET 10のASP. NET Core注目の新機能
tomokusaba
0
140
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
970
自然言語でAPI作業を片付ける!「Postman Agent Mode」
nagix
0
150
レガシーシステム刷新における TypeSpec スキーマ駆動開発のすゝめ
tsukuha
4
800
SRE視点で振り返るメルカリのアーキテクチャ変遷と普遍的な考え
foostan
2
2.4k
クラスタ統合リアーキテクチャ全貌~1,000万ユーザーのウェルネスSaaSを再設計~
hacomono
PRO
0
200
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
54
7.9k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
[RailsConf 2023] Rails as a piece of cake
palkan
57
6.1k
The Art of Programming - Codeland 2020
erikaheidi
56
14k
Code Review Best Practice
trishagee
72
19k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Rails Girls Zürich Keynote
gr2m
95
14k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
31
2.7k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Making the Leap to Tech Lead
cromwellryan
135
9.6k
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)