Занятно, что автор статьи преподносит vSwap как плюс. Это костыль, который приводит к следующим проблемам:
1) Учёт памяти страницами приводит к аварийному завершению процесса, который стал причиной выделения страницы, которая не может быть выделена. Например, все страницы забрали процессы apache, а oom-killer решил прибить mysql. Имеем битые базы.
2) Вытеснение swap в память может иметь противоположный описанному результат. Операционная система — не дура, и откачивает редкоиспользуемые страницы, а вместо них загружает, например, дисковый кеш. Если своп от впсок будет висеть вместо дискового кеша, то общая производительность упадёт.
3) Искуственное замедление доступа к памяти — полный бред. Много одновременных запросов -> превышение лимита на память -> ещё больше одновременных запросов -> падение.
Мы от него используем только первую возможность, потому что она в некотором смысле повторяет поведение реальной операционной системы и все, кого это волнует, к этому привыкли.
Кроме того, сейчас OpenVZ рекомендует переходить на ploop, что отменяет Ваши аргументы про миграцию (т.к. копирование блочного устройства будет идти одинаковое количество времени на всех гипервизорах, а, очевидно, именно это самое узкое место) и уплотнение ФС (которое приводит к очень злым проблемам при оверселлинге).
В своё время OpenVZ действительно был нужен и полезен. Когда аппаратная виртуализация стала иметь сравнимые с текущими стабильность и оверхед, технология стала применима лишь в очень узком спектре вроде разещения на одном сервере 10000 виртуалок, каждая из которых обрабатывает по 3 запроса в день.
>Раздел /boot, большинство дистрибутивов рекомендуют для него 512kB.
Вы уверены, что именно kB? Один initramfs от RHEL6 занимает примерно 15 мегабайт, ядро — ещё 4.
Нативные нити реализуют только одну возможность — запустить указанную функцию в новом потоке.
QThread'ы предоставляют к этому объектно-ориентированный интерфейс и запускают в потоке цикл обработки событий.
Логично, что на освоение более широкого инструмента ушло больше времени.
Это не так. Старые клиенты могут активировать новые лицензии ksplice на машины под управлением любой ОС. То есть привязка, фактически, не к дате покупки подписки, а к дате заведения аккаунта (когда речь идёт о неединичном заказе)
А я в своём вопросе говорил том, что сохранаяя весь смысл можно перейти к другой реализации.
Лично для меня под вопросом именно нужность третьего варианта splice() за O(1) — поиск итераторов всё равно в общем случае занимает линейное время, поэтому экономия получается сомнительная. В указанном ниже примере find можно заменить два цикла, использующие второй вариант splice() и на два вызова первого варианта, получив такую же сложность.
В более сложном случае (когда мы запоминаем итераторы одного списка, изменяем этот список, а затем делаем splice() в другой список) выхода действительно нет, но я пока не смог придумать пример реальной частовстречающейся задачи, где может понадобиться такая операция.
Если Вы говорите с точки зрения стандарта, то есть три перегруженные версии splice() — одна принимает список и вставляет его целиком, вторая — список и итератор и вставляет один элемент, третья — список и два итератора и вставляет диапазон.
Первые две версии продолжат работать за O(1), как и требует стандарт (в первом случае размер вставляемой части уже посчитан, во втором случае вставляется только один элемент).
Третья версия должна работать за O(1) только при splice из списка в самого себя (23.2.2.4.14) (а в этом случае размер списка не изменяется), в противном случае ей разрешается линейное время.
Если Вы говорите с точки зрения выбора trade-off, то с этим ничего нельзя сделать — есть два пути, одна популярная реализация выбрала один путь, другая — другой, а в стандарте нужно либо закрепить один из них, либо оставить всё как есть.
А что мешает обязать list выдавать значение, удовлетворяющее данной семантике, за константное время?
Например, несмотря на то, что для натуральных чисел сумму sum(a, b) можно определить как sum(next(a), prev(b)) при b != 1 и next(a) при b=1, никто не запрещает нам реализовывать сложение более эффективно.
1) Учёт памяти страницами приводит к аварийному завершению процесса, который стал причиной выделения страницы, которая не может быть выделена. Например, все страницы забрали процессы apache, а oom-killer решил прибить mysql. Имеем битые базы.
2) Вытеснение swap в память может иметь противоположный описанному результат. Операционная система — не дура, и откачивает редкоиспользуемые страницы, а вместо них загружает, например, дисковый кеш. Если своп от впсок будет висеть вместо дискового кеша, то общая производительность упадёт.
3) Искуственное замедление доступа к памяти — полный бред. Много одновременных запросов -> превышение лимита на память -> ещё больше одновременных запросов -> падение.
Мы от него используем только первую возможность, потому что она в некотором смысле повторяет поведение реальной операционной системы и все, кого это волнует, к этому привыкли.
Кроме того, сейчас OpenVZ рекомендует переходить на ploop, что отменяет Ваши аргументы про миграцию (т.к. копирование блочного устройства будет идти одинаковое количество времени на всех гипервизорах, а, очевидно, именно это самое узкое место) и уплотнение ФС (которое приводит к очень злым проблемам при оверселлинге).
В своё время OpenVZ действительно был нужен и полезен. Когда аппаратная виртуализация стала иметь сравнимые с текущими стабильность и оверхед, технология стала применима лишь в очень узком спектре вроде разещения на одном сервере 10000 виртуалок, каждая из которых обрабатывает по 3 запроса в день.
cgroups+blkio-лимиты?
Вы уверены, что именно kB? Один initramfs от RHEL6 занимает примерно 15 мегабайт, ядро — ещё 4.
QThread'ы предоставляют к этому объектно-ориентированный интерфейс и запускают в потоке цикл обработки событий.
Логично, что на освоение более широкого инструмента ушло больше времени.
Но лисята милые :)
Лично для меня под вопросом именно нужность третьего варианта splice() за O(1) — поиск итераторов всё равно в общем случае занимает линейное время, поэтому экономия получается сомнительная. В указанном ниже примере find можно заменить два цикла, использующие второй вариант splice() и на два вызова первого варианта, получив такую же сложность.
В более сложном случае (когда мы запоминаем итераторы одного списка, изменяем этот список, а затем делаем splice() в другой список) выхода действительно нет, но я пока не смог придумать пример реальной частовстречающейся задачи, где может понадобиться такая операция.
В мемориз
Первые две версии продолжат работать за O(1), как и требует стандарт (в первом случае размер вставляемой части уже посчитан, во втором случае вставляется только один элемент).
Третья версия должна работать за O(1) только при splice из списка в самого себя (23.2.2.4.14) (а в этом случае размер списка не изменяется), в противном случае ей разрешается линейное время.
Если Вы говорите с точки зрения выбора trade-off, то с этим ничего нельзя сделать — есть два пути, одна популярная реализация выбрала один путь, другая — другой, а в стандарте нужно либо закрепить один из них, либо оставить всё как есть.
Например, несмотря на то, что для натуральных чисел сумму sum(a, b) можно определить как sum(next(a), prev(b)) при b != 1 и next(a) при b=1, никто не запрещает нам реализовывать сложение более эффективно.