Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Уроците от работата ми по WordPress.com - Веселин Николов

423 Aufrufe

Veröffentlicht am

Veröffentlicht in: Präsentationen & Vorträge
  • Als Erste(r) kommentieren

Уроците от работата ми по WordPress.com - Веселин Николов

  1. 1. Уроците от работата ми по WordPress.com Веселин Николов
  2. 2. За мен ● Веселин Николов ● @dzver ● Работя в Automattic ● PHP, MySQL, WordPress
  3. 3. Работата ми преди ● MS SQL Server 2005 ● MySQL < 5.1, 5.1 ● 1-2-3 сървъра ● Сложни схеми ● Недостатъчни ресурси
  4. 4. Работата ми преди ● Stored Procedures ● Triggers ● SQL Jobs живеещи в DB сървъра ● Конструирани заявки с много случаи ● Materialized Views ● Foreign Keys ● Продължителна замяна на логика с курсори с логика без курсори
  5. 5. Умножете по 1000 ● Проблеми с натоварване и много работа по оптимизиране на сложните заявки ● Денормализация ● Много промени в схемата
  6. 6. После си смених работата.
  7. 7. Шок ● Примитивни заявки, предимно primary key lookups. Join decomposition. ● Редки и твърде скъпи промени в схемата ● Нови проблеми като replication lag и риск от чупене услугата
  8. 8. Работата ми сега ● MySQL ● Прости заявки ● Огромни обеми заявки ● Множество сървъри ● WordPress ● Memcached
  9. 9. Често срещани проблеми ● Много на брой заявки ● Заявки по големи таблици без индекси ● Offsets ● Много сортиране ● Избиране на голям обем данни
  10. 10. Често срещани проблеми ● Много на брой заявки ● Заявки по големи таблици без индекси ● Offsets ● Много сортиране ● Избиране на голям обем данни
  11. 11. Много на брой заявки ● Нещо много навътре в кода вика не- кеширана заявка.
  12. 12. Решения ● WordPress Debug Bar https://wordpress.org/plugins/debug-bar/ ● WordPress Options API http://codex.wordpress.org/Options_API ● Caching wp_cache_set, wp_cache_get
  13. 13. Debug Bar ● В тестова среда показва всички заявки ● Може да показва и всички hooks, remote requests, memcached stats etc.
  14. 14. Log ● MySQL Slow Log вече поддържа 0 сек ● Може да се ползва pt-query-digest ● SHOW FULL PROCESSLIST ● SHOW PROFILE ● MS SQL има безкрайно удобен профайлър :-)
  15. 15. Options API ● Таблица с keys и values ● Кеширана е като 1 масив за blog ● Масивът се съхранява в глобална променлива (чрез object cache) ● Инвалидация на кеша при set/add/delete => 1 заявка на много хиляди requests
  16. 16. Кеширане ● Не е нужно да се кешира всичко ● Има много нива на кеширане - Object Cache - Query Cache - Memcached - Batcache И понякога денормализация
  17. 17. Кеширане. MySQL Query Cache Query Cache = 0 ● Кешът се инвалидира при всеки insert/update ● Овърхедът често е по-голям от ползите ● В някои случаи е полезен, но в рамките на „десетки мегабайти“.
  18. 18. Кеширане. Batcache WordPress plugn за съхраняване на цели страници в Memcache или APC ● http://evansolomon.me/notes/faster-wordpress-multisite-nginx-batcache/ ● https://wordpress.org/plugins/batcache/ ● http://xkcd.com/908/
  19. 19. wp_cache_get, object cache ● wp_cache_get, wp_cache_add, wp_cache_set, wp_cache_delete ● Object Cache за избягване на повторни обръщения към Memcahce
  20. 20. Често срещани проблеми ● Много на брой заявки ● Заявки по големи таблици без индекси ● Offsets ● Много сортиране ● Избиране на голям обем данни
  21. 21. Липса на индекс ALTER `table` ADD index .. Всеки сложен проблем има едно просто решение, което обикновено е грешно.
  22. 22. Липса на индекс ● Индексите са скъпи ● Обновяването им натоварва сървъра ● Поддържането им в паметта е скъпо ● Допълнителен овърхед за query optimizer ● Не е голяма беля, ако не се събират в паметта.
  23. 23. Често срещани проблеми ● Много на брой заявки ● Заявки по големи таблици без индекси ● Твърде много индекси ● Offsets ● Много сортиране ● Избиране на голям обем данни
  24. 24. Липса на индекс - решения ● Употреба на прости заявки ● Отбягване на комплексни JOINs ● EXPLAIN SELECT преди commit ● Primary Key само по `id` данните са клъстърирани по PK, употреба на комплексен PK може да е полезна в някои приложения
  25. 25. Липса на индекс For join queries, the number of possible plans investigated by the MySQL optimizer grows exponentially with the number of tables referenced in a query. http://dev.mysql.com/doc/refman/5.7/en/controlling-query-plan-evaluation.html
  26. 26. Малко за индексите При индекси върху повече от 1 поле, редът има значение: INDEX foo(A, B, C) ● WHERE A = 3 ● WHERE A = 3, B = 4, C = 5 ● WHERE B = 5, C = 7
  27. 27. Често срещани проблеми ● Много на брой заявки ● Заявки по големи таблици без индекси ● Твърде много индекси ● Offsets ● Много сортиране ● Избиране на голям обем данни
  28. 28. Offsets http://mysite.com/offers/3 SELECT * FROM ... LIMIT 30, 10 http://mysite.com/offers/309091 SELECT * FROM ... LIMIT 3090910, 10
  29. 29. Offsets Такива ситуации възникват при ● Страници ● One-time скриптове ● Cronjobs, нотификации, какво ли не.
  30. 30. Offsets Прости решения: SELECT * FROM ... WHERE `id` > 1093029 LIMIT 20 SELECT * FROM ... WHERE `ts` BETWEEN '2014-04-11' AND ...
  31. 31. Offsets Сложно решение: SELECT * FROM `table` JOIN ( SELECT `id` FROM `table` ORDER BY `whatever` LIMIT 5000,50 ) as `b` USING `id`
  32. 32. Често срещани проблеми ● Много на брой заявки ● Заявки по големи таблици без индекси ● Offsets ● Много сортиране ● Избиране на голям обем данни
  33. 33. Сортиране Using filesort; Using temporary; ● Не е rocket science ● Сортиране по индексирана колона ● Индексът е подреден ● Ако подходящ индекс за вашата заявка, сървърът ползва filesort
  34. 34. Сортиране SELECT * FROM `table` WHERE A = 3 ORDER BY B ... ORDER BY A DESC, B DESC За такава заявка е нужен индекс по A, B (в този ред)
  35. 35. Още малко за индекси... INDEX(A,B) няма да се ползва при: ● WHERE A > 5 ORDER BY B ● WHERE 1=1 ORDER BY B ● ORDER BY A DESC, B ASC http://www.percona.com/files/presentations/WEBINAR-MySQL-Indexing-Best-Practices.pdf
  36. 36. Antipattern ● ORDER BY RAND() : WHERE ID IN (5, 14, 33) WHERE ID > %d LIMIT 1 shuffle();
  37. 37. Antipattern Употребата на функции в заявките прави безполезен Query Cache SELECT * FROM `table` WHERE my_date = current_date() SELECT * FROM `table` WHERE my_date = '2014-05-19'
  38. 38. SELECT на много данни ● Cronjobs, one-time scripts ● Вътрешно паджиниране по ID ● Работа с блокове от по 100-1000 записа
  39. 39. WordPress.com специфики ● 500 000 000+ таблици ● 600+ DB сървъра ● Master/Slave, partitions, shards, често таблиците са на различни сървъри ● HyperDB to rule them all
  40. 40. HyperDB ● HyperDB е мощен DB клас ● Поддаржа репликация ● Парсва заявките, за да открие към кои сървъри да се закачи ● Поддържа read и write servers ● Поддържа partitions
  41. 41. HyperDB ● Обичайно чете от slaves (read servers) ● Винаги пише в masters ● При UPDATE/INSERT преминава към master сървър за дадената таблица
  42. 42. Replication Lag ● Мастър сървърът получава заявка ● Заявката се записва в бинлог ● Заявката се изпълнява на мастъра ● Слейвът създава thread, който се закача към мастъра и изисква новите заявки ● Мастърът създава binlog dump за всеки слейв ● Слейв сървърът изпълнява заявките http://barry.wordpress.com/2011/07/20/hyperdb-lag-detection/
  43. 43. Replication Lag Много неща могат да се счупят: ● Слейвът може да не може да изпълни заявките със същата скорост ● Бавни заявки на слейва или explicit locks могат да принудят нишката, която синхронизира да чака ● Бавните заявки на мастъра ще са все така бавни и на слейва ● Disk I/O, Network issues
  44. 44. Replication Lag Защо е лошо: ● Възможно е да се прочетат стари данни ● Възможно е да се запишат стари данни ● HyperDB знае кои сървъри са лагнати, но това не ни спасява да мислим заявките си.
  45. 45. WordPress.com специфики ● Предпочитаме голямо количество малки заявки пред малко количество големи ● Таблиците може да не се виждат една друга в текущия connection на HyperDB ● Рядко ползваме JOINS
  46. 46. WordPress.com специфики ● Употребата на дебели JOINS във вашия проект може да е оправдана ● Избягвайте correlated subqueries ● Ако базата данни поддържа материализирани изгледи, why not? (CouchDB, MS SQL, PostgreSQL)
  47. 47. Joins... ● Полетата, които се ползват в ON / USING трябва да са с индекси ● GROUP BY / ORDER BY трябва да са по една таблица ● Ползвайте JOIN вместо всякакви форми на subquery
  48. 48. Търсене ● LIKE '%foo%' - лоша идея. ● LIKE 'foo%' - възможен индекс ● MATCH ( name ) AGAINST ( 'foo' ) - Full Text Search (поддържа се от MyISAM и InnoDB MySQL 5.6+) ● SphinxSearch, Lucene, Solr, ElasticSearch
  49. 49. AMA
  50. 50. Благодаря!

×