31 март 2009

Програмиране отдолу-нагоре

1993
Оригиналната публикация - Programming Bottom-up
(Това есе е част от въведението на On Lisp . Червеният текст обяснява произхода на името Arc)
Стар принцип в програмирането е функционалните елементи на програмата да не са много големи. Ако някой компонент от програмата премине границата на четимост той придобива голяма сложност, която прикрива грешките както големият град прикрива престъпленията. Подобен софтуер е труден за четене, труден за тестване и труден за дебъгване.
Спрямо този принцип големите програми трябва да се разделят на части и колкото по-голяма е програмата на толкова повече части трябва да се раздели. Как да се раздели програмата ? Традиционният подход се нарича отгоре надолу - "тази програма трябва да прави тези седем неща, така че ще я разделя на седем големи процедури. Първата процедура трябва да прави тези четири неща, затова тя ще има четири собствени подпроцедури...". Този процес продължава до достигането на опрелена степен на гранулиране - всяка част е достатъчно голяма, за да върши нещо, и достатъчно малка, за да не може да се разделя повече.
Опитните Lisp програмисти разделят своите програми по различен начин. Те използват принцип, наречен отдолу-нагоре -- променят езика според проблема . С Lisp не само програмата се пише на езика, но и езика се изгражда спрямо програмата . Докато пишете програмата може да си помислите "Искам Lisp да има такъв и такъв оператор" . След това си го написвате. В последствие разбирате , че използването на новият оператор може да опрости друга част от програмата и така нататък. Езика и програмата се развиват заедно. Границите между ези ки програма се чертаят и пречертават като граница между воюващи държави, докато не стигнат до планини и реки, които да са естествени граници . В края програмата изглежда така, сякаш езикът е проектиран за нея. А когато езикът и програмата са един за друг кодът е чист, малък и ефиктивен.
Струва си да се отбележи, че проектирането отдолу-нагоре не означава просто различен ред за написване на програмата. При работа отдолу-нагоре в края имаме различна програма. Вместо една монолитна програма имаме по-голям език с повече абстрактни оператори и по-малка програма , написана на него.Имаме арка вместо греда.
След намирането на абстракните части, които често са известни, от нормалния код остава доста малко; колкото повече се допълва езика , толкова по-малко разстояние остава за да се достигне целта. Това има няколко предимства:
  1. Когато езика върши повече работа самата програма е по-мала и по-лесно променима. По-малката програма не трябва да се разделя на много компоненти, а малкото компоненти правят програмта по-лесна за четене и модифициране. По-малкият брой компоненти води и до по-малко връзки между тях , както и до по-малка вероятност за грешки в тях. Опитните Lisp програмисти използват проектирането отдолу-нагоре за намаляване на размера и сложността на техните програми по подобие на индустриалните проектанти, които намалят броят на движещите се части в машините.
  2. Проектирането отдолу-нагоре увеличава повторното използване на кода. Много от полезните елементи написани за една програмамогат да се използват и в следващите я. След насъбирането на голям набор от малки части код писането на нова програма заема малка част от усилията ,които ще трябват ако се пише начисто.
  3. Проектираните отдолу-нагоре програми са по-лесни за четене. Този тип абстракция налага читателят да разбере оператор с общо предназначение; функционалната абстракция налага читателя да разбере процедура със специално предназначение. [1]
  4. Работата отдолу-нагоре помага за изясняването на дизайна на програмата, тъй като изисква постоянно търсене на шаблони в кода. След забелязването на сходност в два отдалечени компонента в програмата може да се стигне до препроектирането й в по-проста форма
Проектирането отдолу-нагоре е възможно и в езици, различни от Lisp. Всяка библиотечна функция е част от такъв дизайн. Въпреки това Lisp дава много по-голяма свобода в това направление и нарастването на езика играе голяма роля в стила на Lisp. Толкова голяма, че Lisp не е само различен език, а различен стил на програмиране.
Истина е че този стил на програмиране е пригоден за програми, които се пишат от малки групи. Въпреки това той разтегля границите на това, което може да се направи от малка група. Фредерик Брукс, в книгата си The Mythical Man-Month предполага, че продуктивността на групата не зависи линейно то размера й. С нарастването на размера на групата се намалява продуктивността на отделния програмист. Опитът от програмиране на Lisp води до по-оптимистичен вариант на този закон : Намаляването на групата води до увеличаване на продуктивността на отделния програмист . Малките групи печелят , относително погледнато, просто защото са по-малки. Когато малка група се възползва от предимствата на Lisp , тя може да спечели.


Download On Lisp for Free.

[1] Но никой не може да разбере програмата без да разбира всички нови оператори." Това твърдение е опровергано в Секция 4.8.

06 март 2009

Архитектурата на Mixi.jp

Mixi е бързо нарастваща японска социална мрежа. Предоставят услуги като дневник, общност, съобщения, фото албум. Имайки много общо с LiveJournal те са използвали сходен подход.

http://mixi.jp

Източник на информация

mixi.jp - мащабиране с отворен код

Платформа


Вътрешна организация

  • Имат приблизително 4 милиона потребители, които нарастват с повече от 15 000 на ден.
  • На 35-то място в Alexa и 3-то в Япония.
  • Повече от 100MySQL сървъра
  • Добавят повече от 10 съвъра на месец
  • Използва non-persistent връзки.
  • Трафика в дневниците е 85% четене и 15 % запис.
  • Трафика от съобщения е 75% четене и 25% запис.
  • Имаха проблеми с производителността при репликация, които са решени чрез разделяне на базата от данни.
  • Избор между вертикално разделяне (по потребител) и хоризонтално разделяне(по тип на таблицата).
  • Крайното разделяне е по тип на таблицата и потребител. По този начин всички съобщения на група от потребители ще се намират в определена база от данни. За избор на базата от данни, в която да се запише нещо се използва ключ.
  • За кеширане използват memcached с 39 машини Х 2 ГБ памет.
  • Съхраняват повече от 8 ТБ изображения като всекидневно се добавят около 23 ГБ.
  • MySQL съхранява само метаданни за изображенията, но не и самите тях.
  • Изображенията се делят на често и рядко достъпвани.
  • Често достъпваните изображения са кеширани от Squid на няколко машини.
  • Рядко достъпваните изображения се намират само във файловата система. Няма полза да се кешират.

  • Поуки

  • При използването на динамично разделяне е трудно да се избират ключове и алгоритми за мястото на данните.
  • Не може да се използва join при разделени данни, така че за събирането на информация трябва да се отворят много връзки към различните бази от данни.
  • Добавянето на нови машини е трудно. Например ако алгоритъма за разделяне съхранява всички съобщения на потребители от 1 до N в хост 1. Когато този хост се претовари ще трябва да разделим потребителите на повече хостове. Това е много трудна задача.
  • Използването на разпределено кеширане води до редки обръщения към БД и средното време за зареждане на страница е около 0.02 секунди. Това намаля проблемите свързани с разделянето на данните.
  • Често трябва да се използват стратегии за определен тип съдържание. Например изображенията ще се обработват по различен начин от кратките текстове.
  • Социалните мрежи са времево ориентирани, така че има смисъл разделянето на данните да става освен по потребител и тип, така и по време.
  •