Pull to refresh
112
0
Марк Шевченко @markshevchenko

программист

Send message
> а если сервера в разных датацентрах, что при раздаче файлов и получается?

У меня подобного опыта нет. Думаю, что при таких объёмах и решение будет уникальным, и одним rsync здесь не обойтись. Более того, это отдельная задача и в рамках текущей дискуссии. Одно дело хранить файлы в дополнение к какому-то основному функционалу, где требуется активно задействовать SQL. Совсем другое — специализироваться на терабайтах и датацентрах. Подозреваю, что для такой задачи SQL не сильно нужен.

> файлы перегнать через rsync — легко, а реплицировать базу?

Если в SQL всё равно хранить часть информации, то придётся реплицировать и файлы, и базу. Вот в этом случае вероятность рассинхронизации возрастает многократно. Представьте: база уже новая, а файлов ещё нет. Вот если всё лежит в базе, или всё в файлах, тогда проблем меньше.

> И мы получаем ещё одну возможную проблему. Длительность транзакций резко
> увеличивается при хранении файлов, наверняка будут проблемы с целостностью базы.

Э-э-э-э… Мы про что сейчас говорим? Теряю нить рассуждения. Про blobstreaming для mysql из ссылки выше?
Ну вот я и интересуюсь — в чём проблема в 1000 соединений с MySQL? Ну, пусть 20 килобайт занимает каждое соединение, 1000 соединений это 20 мегабайт ОЗУ. Какие ещё накладные расходы?

Кстати, я подозреваю, что решение, ссылку на которое я выше кидал (blobstreaming.com) не требует отдельных подключений.

По последнему пункту: пока не понял, в чём проблема с масштабированием. Поставили два сервера, три, четыре — разве не будет работать? Почему?
Вы, наверное, про Oracle больше имели в виду.

В MS SQL я такой возможности не помню, полез искать — так и есть, нововведение в 2008 версии. :)
Тут уж надо определяться: если речь о большом проекте, где возможна одновременное скачивание 1000 файлов, надо выносить эту базу на отдельный сервер, как у меня и предложено.

Вообще же, накладных расходов там должно быть немного: индекс по имени файла в оперативке, а это вообще копейки (скажем, миллион файлов при средней длине пути 60 символов вполне уложится где-то в 80 метров). Сколько то килобайт на каждое подключение, при 1000 подключений это тоже мегабайты. Всю остальную оперативку можно выделить под дисковый кеш — те файлы, которые чаще скачиваются, будут лежать в оперативке и отдаваться ещё быстрее.

Одна беда — без blob streaming есть только один способ прочитать файл — весь его скачать в оперативку. Вот это уже засада.
Тут всё-таки есть одна тонкость. Сам пример показывает, что для ФЯ map и reduce не являются чем-то искусственным. Наоборот, они из ФП как раз и пришли. И параллелятся они прекрасно сами по себе, ну вот разве с reduce бывают сложности.

А вот как будет распараллелен приведённый код на Си++, я не знаю. Думаю, будут серьёзные сложности, если речь идёт об автоматическом распараллеливании. Вручную, конечно, без проблем.

Про доступность есть две точки зрения. С одной стороны, всё это уже можно крутить в личных проектах на свой страх и риск. Там много интересных наработок, например, DLR (поддержка динамических языков) и F# (язык на базе OCaml, где параллельность уже по умолчанию должна работать). Но на работе на боевой сервер не дадут PE поставить, пока не выйдет официальный .NET 4. :)

Поэтому с одной стороны всё уже есть, а с другой — ждём. :)
Спасибо. Буду иметь в виду.

В тех проектах, в которых я участвовал, верхняя граница была где-то в районе 7-8 метров, наверное, потому и не было заметно больших просадок. Для отправки контента использовались ADO.NET, где есть операции поблочного чтения блобов.
Полез проверять. С удивлением обнаружил, что MySQL не поддерживает работу с блобами, как с потоками, даже в C API.

Зато оказалось, что в сети есть несколько проектов BLOB streaming engine extention, например, вот: blobstreaming.org/

Причём у них даже HTTP-сервер простой реализован, так что даже скрипт писать не надо.
Такой ли уж «огромный удар по производительности»? Интересуюсь серьёзно — есть ли какие-нибудь замеры?

Вот для обсуждения такая архитектура: выделенный MySQL/ngnix сервер для хранения файлов. В MySQL на каждый проект одна база, в базе одна таблица Files с теми полями, которые у Вас в статье описаны. Эта таблица связывается с таблицами Вашего проекта, которые находятся на другом сервере. Поддержка целостности ложится на плечи SQL-сервера.

На ngnix запущен простой скрипт, который по path находит запись (если не найдена, возвращает 404), открывает BLOB для потокового чтения и тупо всё отдаёт. Единственную сложность вижу здесь: надо протестировать заголовки HTTP Location и Length, чтобы докачка поддерживалась, для больших файлов это надо.

При таком подходе данные практически прямо с диска попадают в TCP stream. Теоретически просадка по производительности составит, ну, 2-3-5%, никак ни 20, ни 30%. Вы проверяли, как будет на практике? Может оказаться работоспособным вариантом.
Мне кажется, у Вас тут личное отношение проявляется, а не итог серьёзных раздумий. Серьёзно.

> Если лидер пытается совместить роли, то это из-за экономии или из-за непонимание психологии.
> Экономия — чаще всего от бедности или от жадности.

Далеко не всегда. Тестирование — это серьёзная задача, которая требует для решения самых разных специалистов. Участие в тестировании разработчиков, на мой личный взгляд — весьма полезная практика. Знаете, например, как улучшить стиль собственного программирования? Разбираться в чужом коде. После такой работы появляется кровью заработанное знание, зачем и как писать понятный код. Точно также, для выработки навыка безопасного программирования требует перекрёстное тестирование.

Однако, это не означает, что не должно быть отдельных тестировщиков, которые погоняют код на неверных данных, или пользователей, которые скажут — удобно ли, понятно ли. Или специалистов по нагрузочному тестированию.

> 1. Разработчики — это созидатели.
> 2. Тестировщики — разрушители. Эффективность тестирования при прочих равных выше у того,
> кто намеренно ломает систему.

Красиво, но к реальной жизни имеет мало отношения. Эффективность выше у того, у кого больше знаний об устройстве. Он и построит хорошо, и сломает тоже хорошо.

> 1. Профессионал всегда эффективнее, чем смежник или универсал. Аксиома.
> 2. Иногда хороший ИТ-професионал может показать результаты лучше какого-нибудь тестировщика. Но
> стоимость такого ресурса может оказаться намного выше стоимости привлечения тестировщика.

Логично. Тем не менее, Вы пишете, скорее всего, о том, что тестированием должны заниматься «студенты» (самые неопытные разработчики в команде). Которые сами хотят стать разработчиками.
Если писать, то с тем же «неминусующим» отношением к читателям. Тогда «PHP — говно» превращается в «PHP хорошо подходит в определённых случаях, но в некоторых большинстве современных крупных проектов лучше подходят другие средства разработки».

Правда, при таких формулировках никакой почвы нет для холивара. :)
Тут имеет смысл рассмотреть правомерность употребления слов «некрасивый» и «уродский». Если код предназначен для чтения человеком, можно говорить о стиле.

А если нет? В чём смысл? Код страницы не отформатирован, из скриптов выброшены все пробелы и отступы, переменные названы a, v, k, все из одной буквы. Это характерно для любого фреймворка, не только для ASP.NET.

Так Вы и озвучьте полную свою позицию: Вы против фреймворков, за ручную вёрстку. И минусов Вам поставят ещё в два раза больше. :)
Здесь дело не в синтаксическом сахаре. [1..3..11] это действительно ерунда. Основное достоинство ФП — в данном случае и map и reduce уже выполняются параллельно. То есть, это не теоретическая возможность, существующие системы уже так работают.

И основное отличие в том, что (если, например, мы хотим составить таблицу синусов до миллионного знака после запятой), код на Си++ нужно будет распараллеливать вручную. А код на OCaml нет. Вот он такой, какой есть, и останется.

Здесь речь не о краткости кода (в Си++ вычисление факториала можно было бы вынести в отдельную функцию, но тут уж тяга к правде сыграла — так не пишут). Только о возможности автоматического распараллеливания.
Точнее написать «не стало такого атрибута». :)
> Для этого в C(++) ничто не мешает особо :)

О, это тема для отдельного холивора. :) Тут можно было бы привести пример с тем самым map-reduce. Само название пошло от двух функций: map (отображение) и reduce (свёртка), которые очень часто применяются в ФП.

Если взять, например, вычисление синуса: sin(x) = x — x^3/3! + x^5/5! ..., то в императивном стиле функция будет выглядеть так:

double sin(double x)
{
  int iteration = 3;
  int sign = -1;
  double factorial = 6;

  double result = x;
  double pow = x * x * x;

  do
  {
    double next = (sign * pow)/factorial;
    result += next;
    sign = -sign;
    pow *= x * x;
    iteration += 2;
    factorial * iteration * (iteration - 1);
  }
  while(iteration <= 11);

  return result;
}


И её довольно трудно параллелить, по крайней мере автоматически. (Неизбежный комментарий: на 11-й итерации мы достигаем наибольшей для double точности в 13 или 14 цифр после запятой). В функциональном стиле она будет уже другой.

let sin_mmbr x i = (x^i * (-1)^((i - 1)/2))/factorial(i)
let after_map x = map (sin_mmbr x) [1..3..11]
let sin x = fold_left (+) 0 (after_map x)


Оба кода писал на ходу, поэтому возможны ошибки и там, и там. Во втором случае главное отличие в том, что здесь не задан порядок вычислений. Есть некий список чисел от 1 до 11 с шагом 2. К каждому числу нужно применить преобразование sin_mmbr. Это map. На этом этапе возможно естественное распараллеливание. Вторая часть — reduce, свести результаты воедино. И эта операция тоже распаралеливается (может, по крайней мере). В данном случае свёртку выполняет функция fold_left.
> SelenIT видимо имеет в виду, что использование обработчиков в тексте
> xHTML-кода — полностью не соответствует идее отделения разметки от
> интерфейсной логики и противоречит концепции «Ненавязчивый JavaScript»

В этом случае возникает вопрос, при чём тут ASP.NET. Я не знаю, много ли фреймворков вообще поддерживают эту концепцию, подозреваю, что из распространнёных ни один. Я подозреваю даже, что концепция появилась позже, чем вышла ASP.NET 1.0.

Если этот подход действительно окажется жизнеспособным, будет и в ASP.NET его поддержка. Всегда надо смотреть. Например, разделение содержания и представления понятно зачем делается. Независимо от фреймворка это полезно. А вот отделение javascript от html — в коде, который автоматом генерируется на сервере…

Ну, чёрт его знает. На мой взгляд, на серверную логику это никак не влияет.

> Когда я смотрю на HTML/CSS/JS-код сгенерированный ASP.Net (особенно
> ранних версий), мне становится страшно :-) Чего только __VIEWSTATE
> стоит!

А вы посмотрите на любой генерированный код любого развитого фреймворка. Он везде страшный. Но Вас почему то угнетает именно ASP.NET. Вот в этом и вижу проявление антимайкрософтовской идеологии.

Так и скажите: ну его на фиг, фреймворки, даёшь возвращение к ручной вёрстке.
> Но, все же, это, показывает, что имитация стека в ассемблерах для старых
> процессоров не является чушью :-)

Это показывает, что на ассемблере Вы не писали, но где-то прочитали, как оно было.

> И это можно привести в качестве примера, пусть и очень старого.

И снова нет. Языки высокого уровня вытеснили язык ассемблера, это факт. И произошло это значительно позже, чем в машинах появилась поддержка стека и вызова функций. По меньшей мере лет на 10. Так что этот факт совершенно ничего не показывает, ни в поддержку Вашей точки зрения, ни для её опровержения. Он просто ни при чём.
А зачем вы так часто используете выделения? Возникает ощущение, как будто вы или кричите, или давите. Зачем?

> Но, несмотря на свою гениальность, преодолеть фундаментальные
> ограничения текстового режима (матрица из 80 * 25, невозможность
> проводить изогнутые линии, 256 цветов и т.д.) она не могла.

Странно, что Вы именно об этом написали. В 91-м году я со своим другом перевёл паскалевскую TV в графический режим. Это оказалось несложно — весь вывод там осуществлялся через одну-единственную функцию, которую мы и переопределяли.

Вывод я писал на ассемблере, и там пришлось серьёзно заниматься оптимизацией. Не знаю, в курсе ли Вы, но в EGA и 16-тицветных режимах VGA вывод осуществлялся через битовые плоскости. Существовало 3 режима вывода, весьма запутанные. В конечном итоге, за месяц удалось довести задачу до конца, и TV работала даже в модных тогда SVGA-режимах 800*600*16. 256 цветов мы не использовали просто потому, что мониторы в те времена не поддерживали высокого разрешения для этих режимов.

А делали мы это для заказчиков, которые писали графические приложения. Естественно, там были и изогнутые линии (эка невидаль! в текстовом режиме даже прямые линии не всегда рисуются). Так что зря Вы говорите, что TV отмерла из-за этого. :)

Кстати, Вы ошибаетесь даже в том, почему именно TV стала столь популярна. Дело в том, что тогда это была единственная ОО-библиотека среди ДОС-программистов (Си++ отставал на 2-3-4 года). Поскольку ОО идеально подходит для интерфейсов, естественно, разрабатывать программы с GUI она позволяла значительно проще.

> Поэтому, она и ушла в историю, уступив место графическим библиотекам
> Windows… (Не потому, что она появилась раньше, или позже Windows, а
> потому, что в Windows-библиотеках отстутствовали фундаментальные
> ограничения текстового режима).

А я ещё раз говорю, что Windows — это среда исполнения, почти операционная система. Там, помимо графической составляющей… Кстати, Вы на Windows API писали когда-нибудь? Там очень неудобно всё делается, поскольку приходиться имитировать ОО-стиль средствами процедурных языков. В TV всё значительно проще и удобнее. На порядок, наверное.

Так вот, в Windows 3.0 помимо графической составляющей была уже невытесняющая многозадачность, виртуальная память, межпрограммное взаимодействие, собственное управление дисками (что естественно, ведь ДОС-овские функции не всегда были реентерабельными). А в 3.1 появилась поддержка локальных сетей.

TV и Windows — это продукты разного класса. Странно, что приходиться писать такие элементарные вещи. Ещё раз думаю, что Вы строите теорию, не опираясь на фактическую базу. А это чревато.

> В этих технологиях пока есть ряд мультимедийных ограничений, которые,
> как не старайся, какую изобретательность не применяй, разработчикам
> web-приложений преодалеть не возможно.
> И, поэтому, HTML/CSS/JS могут уступить тем технологиям, в которых нет
> этих фундаментальных ограничений, например Flex или Silverlight.

Ну вот, вы же сами всё понимаете.

> Но, я надеюсь, под руководтсвом WHATWG эти технологии будут
> развиваться как технологии создания Web-приложений, и «физической
> гибели» не случится.

Вот я и интересуюсь — для чего надеетесь? Зачем держитесь за то, что уже морально устарело? Пока Вы будете играть в бирюльки, вручную на js рисуя графики, остальные разработчики возьмут готовый chart-компонент и будут решать высокоуровневые интересные задачи. Машина должна работать, человек думать — слышали про такое?

> И что, при правильном понимании, работа с HTML/CSS/JavaScript является
> такой же высокоуровневой, что и работа с серверным контролом, а порой,
> и даже более высокоуровневой!

Нет. Высокоуровневая работа это выцеплять ссылочный спам или ненормативную лексику, используя ИИ. Ну, если спуститься чуть на землю, то это использование бизнес-уровня. А этот canvas всего лишь позволит на js делать то же самое, что на Java можно было делать в 97-м году.

> См. пример, где мы можем «на лету» превратить список в дерево, дерево в
> контекстное меню, а в режиме печати снова представит его в виде списка
> и скопировать в виде списка в Word, просто подменив CSS и JS-класс! Такой
> высокоуровневой возможности в серверных контролах нет (поправьте меня,
> если я не прав)!

Конечно, неправы. Всё это бирюльки. Я вообще не понимаю, зачем всё такое сложное нужно, но, как Вы думаете, трудно ли то же самое сделать в Java или Flash или Silverlight? На мой взгляд, достаточно просто, хотя я флеша не знаю. И — речь всё-таки про клиентский код.

> Поэтому я так выступаю за классические HTML/CSS/JavaScript, понимаю из
> высокоуровневость, ценю красоту и гибкость и выступаю против отказа от
> использования это web-парадигмы в строну имитации десктопных GUI!

Мне кажется, Вы просто молоды очень, поэтому Вам и интересно писать yet another чего-то там. А на мой взгляд, времени у нас не так много и тратить его надо на действительно важные вещи.
Они действительно простые, эти примеры. Но оказались очень поучительными для меня в своё время. Взять такой простой паттерн, как singleton. Предположим, есть многопоточная программа, разные потоки в которой должны пользоваться одним и тем же объектом. Возникает вопрос — как его создавать? В однопоточной программе он создаётся по запросу:

Singleton *getSingleton()
{
  static *singleton = NULL;
  if(singleton == NULL)
    singleton = new Singleton();
  return singleton;
}


В многопоточной программе этот код может работать со сбоями. Например, первый поток проверяет singleton, он равен NULL, и поток создаёт объект. Но за это время второй поток успевает создать объект раньше и присвоить значение переменной signleton.

Может так оказаться, что в программе оказываются два одиночки. Очевидно, нужно как то регламентировать создание объекта. В Windows API это делается, например, через критические секции (critical sections). Собственно, это упрощённый вариант блокировки, когда несклько потоков пытаются обратиться к одному и тому же объекту.

Возникает вопрос: когда должна начинаться и когда заканчиваться блокировка? Оказывается, правильный вариант таков:

Singleton *getSingleton()
{
  static *singleton = NULL;
  if(singleton == NULL)
  {
    Lock();
    if(singleton == NULL)
      singleton = new Singleton();
    Unlock();
  }
  return singleton;
}


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

> Нет, его я хотел сравнить с MPI. Имхо они одного порядка решения, а MapReduce
> действительно упрощённый вариант.

Не знаю. Там ведь фишка не только в архитектурном решении, там фишка в LINQ. Нормально параллелятся функциональные языки, и LINQ как раз такой подъязык. Подозреваю, что код на Си++ окажется просто сложнее, поскольку там вся функциональность в шаблонах.

Ну вот, например:

DryadDataContext ddc = new DryadDataContext(dir);
DryadTable<LineRecord> table = ddc.GetTable<LineRecord>(filename);
IQueryable<string> lines = table.Select(lr => lr.line);
IQueryable<string> match = search(lines, searchString);

...

public static IQueryable<string>
search(IQueryable<string> collection,
string searchString)
{
return collection.Where(s => s.IndexOf(searchString) >= 0);
}


Всё, что идёт до вызова table.Select(lr => lr.line) — ввод данных, который на текстовых файлах не параллелится (хотя есть варианты). А вот вызов search уже может выполняться на разных машинах. Главное же то, что не надо писать новую программу для всего этого, нужно добавить три строчки, а всё остальное уже именно так и пишется в C#.

> Просто жаль, что после того, как Microsoft не уделяла внимание HPC и более мирным
> параллельным технологиям, она начала выпускать продукты, как две капли воды воды
> похожие на давно известные решения :)

Почему не уделяла? Им с задачей распараллеливания приходится работать ничуть не меньше, чем гуглу. Из 10-та самых посещаемых сайтов в мире, три или четыре принадлежат Microsoft. Просто сейчас есть почва для промышленных решений — есть сообщество программистов, которые пишут на C#, есть проекты, есть LINQ. Просто всё это не так быстро делается, но делается.
А Вы читать умеете в принципе? Ладно, верю, что умеете, а читать внимательно? Где в моём посте написано, что Windows операционка? У меня там написано «среда исполнения». Пока ещё не операционка, но уже и не библиотека. Причём тут полноценные ОС?

> Ага. А Solaris вообще от 70х годах пишет.

Принимайте к сведению. Работа над NT началась в 85-м году, это раньше, чем работа над TurboVision. Вот и всё.
Я не очень понимаю, в чём ужас. В том, что onClick, а не onclick? Или в том, что javascript?

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity

Specialization

Backend Developer
Lead
From 450,000 ₽
C#
Rust
Algorithms and data structures
Functional programming