Практическое и техническое: dns.dxdt.ru – поиск в DNS

Update: сервис, описанный в этой заметке, более не доступен.

StampsСделал вот сервис dns.dxdt.ru – позволяет искать сведения об адресации, связанные с DNS. Бета-версия. За веб-интерфейсом скрывается база данных из примерно 13 млн документов, которые были получены при помощи опроса доменных зон .ru, .su, кириллической .рф.

Зачем нужно обходить доменные зоны? Давайте вспомним, что DNS работает “напрямую”, то есть в ответ на запрос о “буквенном имени” выдаёт IP-адрес, адрес почтового сервера или ещё что-то. Получить ответ на обратный запрос – “какие домены используют указанный IP-адрес?” – средствами DNS, в общем случае, нельзя. Есть специальные исключения, обратные зоны, но это совсем другая история. Поэтому для того, чтобы провести какой-то поиск, найти “соседей” данного сайта, вычислить общие черты, ещё что-то исследовать – нужно предварительно построить слепок сегмента DNS, опросив серверы имён и сохранив результаты. Собственно, отсюда и получаются все эти миллионы документов.

Как работает dns.dxdt.ru? Интересно было попробовать современные решения. Поэтому в качестве СУБД выбрана MongoDB – это NoSQL СУБД. Сам сервис использует два сервера минимальной конфигурации из амазоновского EC2: на одном работает MongoDB, это, так сказать, “бекэнд”, на втором – связка Apache, PHP, Memcached, это, стало быть, “фронтэнд”. Была идея использовать на “фронтэнде” Ruby, но данный язык, вполне ожидаемо, оказался чудовищно медленным. Отказался. Memcached кэширует не ответы БД, а форматированные результаты выдачи (то есть, итоговые HTML-страницы), что сильно ускоряет работу на повторяющихся запросах. При этом, впрочем, остаётся проблема с доставкой клиенту больших по объёму страниц: некоторые запросы генерируют десятки и сотни тысяч строк в ответе (таковы, например, запросы об ns-ах крупных регистраторов доменов).

Ещё одна особенность: кириллические домены полностью обрабатываются на стороне клиента, Javascript-ом в браузере. То есть, сервер отдаёт и принимает только классическое представление (ASCII), в котором многоязычные имена выглядят как строки с префиксом “xn--“. По-моему, это, прежде всего, идеологически правильно, так как всё “доменное многоязычие” существует именно на клиентском уровне, внутри DNS никаких Unicode-строк нет. Кроме того, реализация многоязычных имён на серверной стороне, вполне предсказуемо, потянула за собой кучу дополнительных задач – преобразование кодировок, контроль этих преобразований, ловля ошибок, обработка “нестандартных” символов и так далее, и тому подобное.

На следующем шаге планирую добавить в dns.dxdt.ru вывод некоторой статистики, обработку MX-ов. Наверное, что-то ещё. Сервис довольно специфический, но всё равно: вопросы, предложения, пожелания – всячески приветствуются в комментариях.

()

Похожие записки:



Далее - мнения и дискуссии

(Сообщения ниже добавляются читателями сайта, через форму, расположенную в конце страницы.)

Комментарии читателей блога: 14

  • 1. 13th June 2012, 15:50 // Читатель Андрей Ситник написал:

    А что именно оказалось медленным в Ruby? Вы использовали голый Ruby (через, например, CGI) или Ruby on Rails.

    Собственно Ruby 1.9 уже быстрее Python 3 и PHP — http://shootout.alioth.debian.org/u32/which-programming-languages-are-fastest.php . Да даже разницу в скорости Ruby 1.8 и Java в Вебе очень трудно заметить — проблемы обычно в других местах (память, база данных).

  • 2. 13th June 2012, 16:04 // Читатель Z.T. написал:

    Каков размер этих документов, что база данных не влезает в оперативную память сервера? Думаю хватило бы SQLite. Есть concurrency и поддержка того же PHP. Вместо memcached с кусочками HTML, в зависимости от сложности страниц, может хватило бы Varnish. Apache не лучший веб-сервер, но не знаю что рекомендуют с PHP (лично я не буду начинать новые проэкты на PHP).

  • 3. 13th June 2012, 18:42 // Читатель Z.T. написал:

    Да, разница между Perl/PHP/Python/Ruby будет не в interpreter а в web app framework. Еще, для Ruby есть JRuby, для Python есть PyPy а для PHP есть HipHop. Но это для тех кто стал очень популярным с кодом на это не рассчитанным. Если знаеш что будет так много requests/sec, пиши с умом для JVM или прямо C++ (Go и D в потенциале).

  • 4. 13th June 2012, 19:10 // Читатель pgrishin написал:

    Прикольно
    http://dns.dxdt.ru/i.php?p=di&q=127.0.0.1
    найдено: 10986

  • 5. 13th June 2012, 19:15 // Александр Венедюхин ответил:

    > А что именно оказалось медленным в Ruby?

    Большие хеши (~ 100 тыс. элементов).

    Да, я использовал 1.8 – наверное, причина могла быть в этом. Как-нибудь проверю на 1.9.

  • 6. 13th June 2012, 19:26 // Александр Венедюхин ответил:

    > Каков размер этих документов,

    На мой вкус, разумный размер (индекс + unicode и т.п.) – байтов 300 в среднем. Но даже в этом оптимистичном случае 13*10^6*300 = 3.9*10^9, а на мелком сервере всего-то 600M ОЗУ. То есть, заведомо не влезает. С другой стороны, Mongo ест около 30G на диске под базу. Тоже перебор.

    > может хватило бы Varnish.

    Может, наверное, но мне проще сконфигурировать Memcached.

    > Apache не лучший веб-сервер,

    Apache просто слишком умный гигантский монстр с кучей неповоротливых щупалец. В этом его проблема. Но быстро поднять что-то для PHP – тут он подходит.

    В принципе, если будет необходимость, я прикручу nginx, конечно.

  • 7. 13th June 2012, 19:28 // Александр Венедюхин ответил:

    > пиши с умом для JVM или прямо C++

    Э-э, хотелось бы ещё без лишней возни с кодом, быстро.

  • 8. 13th June 2012, 19:34 // Александр Венедюхин ответил:

    Кстати, насчёт памяти: Mongo использует memory maped files, что как раз подходит для описанного случая.

  • 9. 14th June 2012, 05:24 // Читатель Z.T. написал:

    Ну, если работать с 30 гига информации с 600 мега памяти, то mmap вместо read(2) экономит только копирование из kernel space в user space. Алгоритм LRU в page cache операционной системы не очень помогает. Я понимаю что система оптимизирована для минимизации время разработки, и это легитимный выбор, но нужно помнить что оптимизированный компактный индекс (read only!) с ключами IPv4 и индекс domains, с 32bit pointers, может быть построен “правильно”.

  • 10. 14th June 2012, 08:14 // Читатель Kir написал:

    Отлично! Просто замечательно! Оценим количество пострадавших доменов в результате некоторых «странных» решений (блокирование сайта по IP) подробности на habrahabr.ru/post/143760/
    Да, порядка 7 тысяч доменов только по этой базе. Надо отметить, что radio-t.com в базу не попал, а значит и другие могли быть тоже пропущены.

    PS И когда решится этот казус не понятно, может попробовать повторно обратиться к провайдеру со ссылкой на эту базу? Потому как сейчас ответ примерно «таково решение суда» (это со стороны Beeline) и «все вопросы к Beeline, у нас он не режется» И похоже единственно на что повлияли обращения, это что забанили другие IP.

  • 11. 14th June 2012, 10:28 // Александр Венедюхин ответил:

    > Надо отметить, что radio-t.com в базу не попал

    Да, там только домены второго (+www) уровня в .ru, .su, .рф. На .com у меня, пока, мощностей нет – > 100 млн имён.

  • 12. 14th June 2012, 10:38 // Александр Венедюхин ответил:

    > но нужно помнить что оптимизированный компактный индекс (read only!) с ключами IPv4 и индекс domains, с 32bit pointers, может быть построен “правильно”.

    Согласен. В принципе, я обдумываю решение со сбалансированным деревом (ну или, окей, с просто деревом) и небольшими файлами результатов, которые хранятся в соответствующей иерархии директорий, а дерево, стало быть, в памяти. Например, предыдущий, сильно упрощённый, вариант по теме сервиса – http://adr.dxdt.ru/ – вообще работал только с Apache, очень быстро.

    Более того, есть “сверхидея” – сравнить решения. Хотя, если говорить о ситуации с разработкой в общем, а не применительно к этому конкретному небольшому проекту, то, в современных реалиях, эффективные архитектура и код всё равно будут побеждены возможностью покупки дополнительного сервера (трёх серверов, пяти больших серверов, “перейдём в облако” и так далее). Ну или, если подходить более системно, то нужно сказать, что аппаратура является ключевым элементом при проектировании сервиса.

  • 13. 14th June 2012, 19:16 // Читатель Z.T. написал:

    IF 100% idempotent GET THEN
    Embarrassingly parallel problem, performance scales linearly with number of cheap performance/watt boxes. Development cost vs. hardware cost depends exclusively on popularity. Use B-Tree, radix tree for best performance w.r.t cache hierarchy. Use C++ for total control of data layout.
    ELSE IF need ACID THEN
    single ACID RDBMS, vertical scaling only until using very expensive hardware (e.g. Sun Fire X4800), then _can no longer scale regardless of budget_, then abandon ACID.
    ELSE
    “eventually consistent” data store.
    END IF

  • 14. 24th June 2012, 21:50 // Читатель jno написал:

    А эрланг поковырять не возбуждает? :)
    Забавнейшая приблуда, однако!