SlideShare une entreprise Scribd logo
1  sur  38
Rewriting
addons.mozilla.org
   with Django
          Jeff Balogh
      github.com/jbalogh
          @jeffbalogh
Oh god how did I
get here I am not
 good with PHP
addons.mozilla.org


          AMO


 github.com/jbalogh/zamboni
addons.mozilla.org


• 165 million request per month
Hardware
• 3 Zeus load balancers
• 24 web servers
 • mod_wsgi: 16 procs, no threading
• 1 MySQL master, 4 slaves
• 3 memcached
• 3 sphinx
• 1 RabbitMQ, 2 celeryd
• 1 Redis master, 1 slave
How we’re
        switching

• One url at a time
• PHP & Python run side by side
class Addon(models.Model):
    name = models.ForeignKey('Translation')
    description = models.ForeignKey('Translation')
    authors = models.ManyToManyField('User')
    # Denormalization
    current_version = models.ForeignKey('Version')



class Translation(models.Model):
    locale = models.CharField()
    localized_string = models.CharField()



class Version(models.Model):
    addon = models.ForeignKey(Addon)
    version = models.CharField()
class Addon(models.Model):
    name = models.ForeignKey('Translation')
    description = models.ForeignKey('Translation')
    authors = models.ManyToManyField('User')
    # Denormalization
    current_version = models.ForeignKey('Version')



class Translation(models.Model):
    locale = models.CharField()
    localized_string = models.CharField()



class Version(models.Model):
    addon = models.ForeignKey(Addon)
    version = models.CharField()
multidb


• github.com/jbalogh/django-multidb-
  router

• Too easy now (thanks Alex & Russel)
Object caching


• github.com/jbalogh/django-cache-
  machine/

• automatically cache all queries
Invalidation
SELECT * from addons ORDER BY rating DESC LIMIT 10

         [<Addon 1865: Adblock Plus>, …]


   md5(SELECT…rating…)        [<Addon 1865>, …]
SELECT * from addons ORDER BY rating DESC LIMIT 10

         [<Addon 1865: Adblock Plus>, …]


   md5(SELECT…rating…)        [<Addon 1865>, …]


  flush:md5(<Addon 1865>)    [md5(SELECT…rating…)]
SELECT * from addons WHERE id = 1865

          <Addon 1865: Adblock Plus>


 md5(SELECT…rating…)        [<Addon 1865>, …]


flush:md5(<Addon 1865>)    [md5(SELECT…rating…)]


 md5(SELECT…id=1865)         <Addon 1865>
SELECT * from addons WHERE id = 1865

          <Addon 1865: Adblock Plus>


 md5(SELECT…rating…)        [<Addon 1865>, …]


                          [md5(SELECT…rating…),
flush:md5(<Addon 1865>)
                          md5(SELECT…id=1865)]


 md5(SELECT…id=1865)         <Addon 1865>
cache.set_many({
     md5(SELECT…id=1865): None,
     md5(SELECT…rating…): None
 }


 md5(SELECT…rating…)      [<Addon 1865>, …]


                         [md5(SELECT…rating…),
flush:md5(<Addon 1865>)
                         md5(SELECT…id=1865)]


 md5(SELECT…id=1865)        <Addon 1865>
Querysets are big
Querysets are big

• cached_with(queryset,   function)

• {% cache obj %}
• From 29r/s to 186r/s
Related objects


• addon.current_version
Related objects


• github.com/simonw/django-queryset-
  transform/

• select_related on steroids
Transforms

Addon.objects.transform(Addon.transformer)

@staticmethod
def transformer(addons):
    addon_dict = dict((a.id, a) for a in addons)
    vs = filter(None, (a.current_version_id for a in addons))
    versions = list(Version.objects.filter(id__in=vs))
    for version in versions:
        addon_dict[version.addon_id].current_version = version
Templates

• {%   load %}

• {% blocktrans with article.price
  as amount %}

• {%   ifnotequal %}
Use Jinja2

• github.com/jbalogh/jingo
• Tags & filters are just functions
• {{ _('Add-ons for {0}')|f(app)     }}
Tests


• github.com/jbalogh/django-nose
• nose makes testing easier
UnicodeDecodeErro
        r

• UnicodeEncodeError: 'ascii' codec
  can't encode characters in
  position 64-72: ordinal not in
  range(128)
UnicodeDecodeErro
        r

• UnicodeEncodeError: 'ascii' codec
  can't encode characters in
  position 64-72: ordinal not in
  range(128)
Django issues

• .filter() is slow
• DELETE CASCADE
• SELECT before UPDATE
Django issues

• .filter() is slow
• DELETE CASCADE
• SELECT before UPDATE
Django issues

• .filter() is slow
• DELETE CASCADE
• SELECT before UPDATE
Does Django scale?

• Yes, with help
• We don’t ship unless it’s faster than
  PHP

• 44,000 lines of PHP vs. 12,500 lines
  of Python
Django @ Mozilla

• “I've been a PHP developer for 8
  years and a Python developer for 6
  months, and I don't want to go
  back.”
http://www.flickr.com/photos/wayneandwax/4731112862/
Jobs Jobs Jobs

• mzl.la/djangocon
• bit.ly/djangocon
• bit.ly uses a single database for all
  their links!
Thank You


• github.com/jbalogh
• jbalogh.me/djangocon.pdf (slides)
References
github.com/jbalogh
github.com/jbalogh/zamboni
github.com/jbalogh/django-multidb-router
github.com/jbalogh/django-cache-machine/
github.com/jbalogh/jingo
github.com/jbalogh/django-nose
github.com/simonw/django-queryset-transform/
mzl.la/djangocon
github.com/mozilla
jbalogh.me/djangocon.pdf (slides)
jbalogh.me/djangocon.txt (this page)

Contenu connexe

Tendances

Introduction to Apache Spark / PUT 06.2014
Introduction to Apache Spark / PUT 06.2014Introduction to Apache Spark / PUT 06.2014
Introduction to Apache Spark / PUT 06.2014bbogacki
 
Realm: Building a mobile database
Realm: Building a mobile databaseRealm: Building a mobile database
Realm: Building a mobile databaseChristian Melchior
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with JasmineTim Tyrrell
 
Julio Capote, Twitter
Julio Capote, TwitterJulio Capote, Twitter
Julio Capote, TwitterOntico
 
Unit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and NodeUnit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and NodeJosh Mock
 
Web sec-淺談
Web sec-淺談Web sec-淺談
Web sec-淺談Jyny Chen
 
Visualizing ORACLE performance data with R @ #C16LV
Visualizing ORACLE performance data with R @ #C16LVVisualizing ORACLE performance data with R @ #C16LV
Visualizing ORACLE performance data with R @ #C16LVMaxym Kharchenko
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングscalaconfjp
 
The Ring programming language version 1.10 book - Part 50 of 212
The Ring programming language version 1.10 book - Part 50 of 212The Ring programming language version 1.10 book - Part 50 of 212
The Ring programming language version 1.10 book - Part 50 of 212Mahmoud Samir Fayed
 
Unit testing with mocha
Unit testing with mochaUnit testing with mocha
Unit testing with mochaRevath S Kumar
 
Hidden Treasures in Project Wonder
Hidden Treasures in Project WonderHidden Treasures in Project Wonder
Hidden Treasures in Project WonderWO Community
 
Solr Indexing and Analysis Tricks
Solr Indexing and Analysis TricksSolr Indexing and Analysis Tricks
Solr Indexing and Analysis TricksErik Hatcher
 
Clojure in the Wild
Clojure in the WildClojure in the Wild
Clojure in the Wildsuitzero
 

Tendances (20)

Introduction to Apache Spark / PUT 06.2014
Introduction to Apache Spark / PUT 06.2014Introduction to Apache Spark / PUT 06.2014
Introduction to Apache Spark / PUT 06.2014
 
Realm: Building a mobile database
Realm: Building a mobile databaseRealm: Building a mobile database
Realm: Building a mobile database
 
Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with Jasmine
 
React for Beginners
React for BeginnersReact for Beginners
React for Beginners
 
Julio Capote, Twitter
Julio Capote, TwitterJulio Capote, Twitter
Julio Capote, Twitter
 
Realm Java
Realm JavaRealm Java
Realm Java
 
Performance patterns
Performance patternsPerformance patterns
Performance patterns
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Unit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and NodeUnit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and Node
 
Web sec-淺談
Web sec-淺談Web sec-淺談
Web sec-淺談
 
Visualizing ORACLE performance data with R @ #C16LV
Visualizing ORACLE performance data with R @ #C16LVVisualizing ORACLE performance data with R @ #C16LV
Visualizing ORACLE performance data with R @ #C16LV
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 
Internal Hive
Internal HiveInternal Hive
Internal Hive
 
Dallas Scala Meetup
Dallas Scala MeetupDallas Scala Meetup
Dallas Scala Meetup
 
The Ring programming language version 1.10 book - Part 50 of 212
The Ring programming language version 1.10 book - Part 50 of 212The Ring programming language version 1.10 book - Part 50 of 212
The Ring programming language version 1.10 book - Part 50 of 212
 
Unit testing with mocha
Unit testing with mochaUnit testing with mocha
Unit testing with mocha
 
第三回Salesforce勉強会
第三回Salesforce勉強会第三回Salesforce勉強会
第三回Salesforce勉強会
 
Hidden Treasures in Project Wonder
Hidden Treasures in Project WonderHidden Treasures in Project Wonder
Hidden Treasures in Project Wonder
 
Solr Indexing and Analysis Tricks
Solr Indexing and Analysis TricksSolr Indexing and Analysis Tricks
Solr Indexing and Analysis Tricks
 
Clojure in the Wild
Clojure in the WildClojure in the Wild
Clojure in the Wild
 

Similaire à Djangocon

Python在豆瓣的应用
Python在豆瓣的应用Python在豆瓣的应用
Python在豆瓣的应用Qiangning Hong
 
國民雲端架構 Django + GAE
國民雲端架構 Django + GAE國民雲端架構 Django + GAE
國民雲端架構 Django + GAEWinston Chen
 
CPAN 模組二三事
CPAN 模組二三事CPAN 模組二三事
CPAN 模組二三事Lin Yo-An
 
자바를 잡아주는 GURU가 있다구!? - 우여명 (아이스크림에듀) :: AWS Community Day 2020
자바를 잡아주는 GURU가 있다구!? - 우여명 (아이스크림에듀) :: AWS Community Day 2020 자바를 잡아주는 GURU가 있다구!? - 우여명 (아이스크림에듀) :: AWS Community Day 2020
자바를 잡아주는 GURU가 있다구!? - 우여명 (아이스크림에듀) :: AWS Community Day 2020 AWSKRUG - AWS한국사용자모임
 
Python & Django TTT
Python & Django TTTPython & Django TTT
Python & Django TTTkevinvw
 
Appsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaolaAppsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaoladrewz lin
 
Everything as a Code / Александр Тарасов (Одноклассники)
Everything as a Code / Александр Тарасов (Одноклассники)Everything as a Code / Александр Тарасов (Одноклассники)
Everything as a Code / Александр Тарасов (Одноклассники)Ontico
 
JavaScript Robotics
JavaScript RoboticsJavaScript Robotics
JavaScript RoboticsAnna Gerber
 
Lecture 03 - JQuery.pdf
Lecture 03 - JQuery.pdfLecture 03 - JQuery.pdf
Lecture 03 - JQuery.pdfLê Thưởng
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disquszeeg
 
Angular Application Testing
Angular Application TestingAngular Application Testing
Angular Application TestingTroy Miles
 
Lessons learned while building Omroep.nl
Lessons learned while building Omroep.nlLessons learned while building Omroep.nl
Lessons learned while building Omroep.nlbartzon
 
Scala Frustrations
Scala FrustrationsScala Frustrations
Scala Frustrationstakezoe
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails TutorialWen-Tien Chang
 

Similaire à Djangocon (20)

Python在豆瓣的应用
Python在豆瓣的应用Python在豆瓣的应用
Python在豆瓣的应用
 
國民雲端架構 Django + GAE
國民雲端架構 Django + GAE國民雲端架構 Django + GAE
國民雲端架構 Django + GAE
 
Django Pro ORM
Django Pro ORMDjango Pro ORM
Django Pro ORM
 
Angular2 for Beginners
Angular2 for BeginnersAngular2 for Beginners
Angular2 for Beginners
 
CPAN 模組二三事
CPAN 模組二三事CPAN 模組二三事
CPAN 模組二三事
 
자바를 잡아주는 GURU가 있다구!? - 우여명 (아이스크림에듀) :: AWS Community Day 2020
자바를 잡아주는 GURU가 있다구!? - 우여명 (아이스크림에듀) :: AWS Community Day 2020 자바를 잡아주는 GURU가 있다구!? - 우여명 (아이스크림에듀) :: AWS Community Day 2020
자바를 잡아주는 GURU가 있다구!? - 우여명 (아이스크림에듀) :: AWS Community Day 2020
 
Python & Django TTT
Python & Django TTTPython & Django TTT
Python & Django TTT
 
Appsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaolaAppsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaola
 
Everything as a Code / Александр Тарасов (Одноклассники)
Everything as a Code / Александр Тарасов (Одноклассники)Everything as a Code / Александр Тарасов (Одноклассники)
Everything as a Code / Александр Тарасов (Одноклассники)
 
Everything as a code
Everything as a codeEverything as a code
Everything as a code
 
JavaScript Robotics
JavaScript RoboticsJavaScript Robotics
JavaScript Robotics
 
Lecture 03 - JQuery.pdf
Lecture 03 - JQuery.pdfLecture 03 - JQuery.pdf
Lecture 03 - JQuery.pdf
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disqus
 
Angular Application Testing
Angular Application TestingAngular Application Testing
Angular Application Testing
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 
Django at Scale
Django at ScaleDjango at Scale
Django at Scale
 
IntroJs
IntroJsIntroJs
IntroJs
 
Lessons learned while building Omroep.nl
Lessons learned while building Omroep.nlLessons learned while building Omroep.nl
Lessons learned while building Omroep.nl
 
Scala Frustrations
Scala FrustrationsScala Frustrations
Scala Frustrations
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails Tutorial
 

Djangocon

Notes de l'éditeur

  1. Python since 2007 Django since 2008 Started at Mozilla in 2009 http://www.flickr.com/photos/morgamic/4466526784/sizes/o/in/set-72157623711339916/
  2. trusted place for hosting for Firefox add-ons sorting, searching, discovery the app store without the store part (at this point)
  3. This talk is about the problems we&amp;#x2019;ve solved getting Django to power a large website
  4. Pinning
  5. what is the race condition?
  6. memcached is not the right place to store sets use redis
  7. cron/celery/signals
  8. /extensions: 14 vs. 150+ queries
  9. ideas from batch_select pick up any relations you&amp;#x2019;re going to use a lot: foreign keys, m2m, reverse relations
  10. Besides denormalization and indexes, I&amp;#x2019;m out of ideas for making the database go faster. Now we&amp;#x2019;ll go into some other things we do differently from a vanilla Django project.
  11. 700 tests run after every commit with Hudson RadicalTestSuiteRunner fixtures (hudson trend graph?)
  12. 400 tests in remora, 700 in zamboni 2,3,5x as fast
  13. sharing code, 4 production site
  14. python developers who love the web, js/frontend devs, operations, other groups