INSTAGRAM UNDER THE HOOD
2020-02-27 210浏览
- 1.INSTAGRAM UNDER THE HOOD Django Under the Hood 2016 Carl Meyer
- 2.
- 3.
- 4.
- 5.4,200,000,000 EVERY DAY
- 6.2,300,000,000,000
- 7.
- 8.October 2010
- 9.“SUPER EASY SET-UP... ONE WAY OF DOING THINGS... EASY TESTING.” — Mike Krieger
- 10.1M Instagrammers December 2010
- 11.
- 12.
- 13.
- 14.
- 15.5M Instagrammers June 2011
- 16.USERS MEDIA LIKES COMMENTS
- 17.class VerticalPartitionRouter(object): DB_FOR_MODEL = { 'likes.like': 'likes', 'comments.comment': 'comments', 'media.media': 'media', } def _db_for(self, model_or_obj): label = model_or_obj._meta.label_lower return self.DB_FOR_MODEL.get(label, 'default') def db_for_read(self, model, **hints): return self._db_for(model) def db_for_write(self, model, **hints): return self._db_for(model) def allow_relation(self, obj1, obj2, **hints): return self._db_for(obj_1) == self._db_for(obj_2)
- 18.
- 19.USERS MEDIA LIKES COMMENTS
- 20.
- 21.LOGICAL SHARDS (PG SCHEMAS) PHYSICAL SERVERS
- 22.LOGICAL SHARDS (PG SCHEMAS) PHYSICAL SERVERS
- 23.commit 5c7034fa8b934569cce5c1bf4bb202f2f3f18bc9Author:Mike KriegerDate:Tue Jul 19 23:47:26 2011 -0700 WIP
- 24.class ShardedObject(object): def insert(self, shard_on_id, from_table, values): shard, db = get_conn_for_shard_key(shard_on_id) cursor = db.cursor() placeholders = ','.join( [("%%(%s)s" % key) for key in values.keys()]) columns = ','.join(values.keys()) insert_statement = ( "INSERT INTO idb%s.%s (%s) VALUES (%s)" % (shard, from_table, columns, placeholders) ) cursor.execute(insert_statement, values) db.commit()
- 25.SHARDED UNIQUE IDS 138726300013410905 TIMESTAMP SHARD ID SEQUENCE CREATE OR REPLACE FUNCTION insta5.next_id... CREATE TABLE insta5.our_table ( "id" bigint NOT NULL DEFAULT insta5.next_id(), ...rest of table schema... )
- 26.
- 27.40M Instagrammers April 2012
- 28.Memcached
- 29.Data center A Memcached Invalidator Data center B Memcached Invalidator
- 30.MULTI-REGION CACHE INVALIDATION
- 31.CONTEMPLATING THE TAO
- 32.TAO Memcached Memcached Memcached Memcached Memcached
- 33.TAO DATA MODEL Jan follows Pat. Pat posts a photo. Jan authors a comment on the photo. Pat likes the comment. Followed by Pat Jan Comment on or ed or ed th th Au Au d ste Po by Has comment es Lik ed Lik Po ste d by by Follows "Contemplative cat!"
- 34.CONTEMPLATING THE TAO
- 35.
- 36.500M Instagrammers June 2016
- 37.UPGRADING DJANGO “JUST KEEP FIXING UNTIL THE TESTS PASS.”
- 38.INSTAGRAM:Now compatible with Django 3.1TM (1.3 + 1.8)
- 39.INSTAGRAM:Now compatible with Django 1.8!
- 40.OUR (MONKEY) PATCHES 1 Don't recompile URL regexes for every active language. 2 Don't try to load translations from an app with no locale directory. 3 Unlazified settings! 40
- 41.UNLAZY ALL THE SETTINGS! from django.conf import settings def force_unlazified_settings(): for key in dir(settings): settings.__dict__[key] = getattr(settings, key)
- 42.INSTAGRAM:Now compatible with Django 1.8! (and fast as ever)
- 43.500M+ Instagrammers Today!
- 44.Proxygen Django & uWSGI TAO Cassandra Everstore Celery & RabbitMQ
- 45.
- 46.
- 47.Active Last Minute ???
- 48.COUNTING CPU INSTRUCTIONS WITH PERF struct perf_event_attr pe; pe.type = PERF_TYPE_HARDWARE; pe.config = PERF_COUNT_HW_INSTRUCTIONS; fd = perf_event_open(&pe, 0, -1, -1, 0); ioctl(fd, PERF_EVENT_IOC_ENABLE); // code whose CPU instructions you want to measure ioctl(fd, PERF_EVENT_IOC_DISABLE); read(fd, &count, sizeof(long long));
- 49.CPU instructions/s CPU instructions/s
- 50.CPU instructions/s CPU instructions/s
- 51.
- 52.AppWeight
- 53.Continuous deployment 30-50 deploys per day
- 54.
- 55.DYNOSTATS class DynostatsMiddleware(object): def process_request(self, req): req.dynostats_enabled = ( 1 == random.randint(1, settings.DYNO_SAMPLE_RATE)) if req.dynostats_enabled:'>enabled: