Как назначить приоритет памяти процессу linux?

Я запускаю Tor на небольшом маршрутизаторе OpenWRT, где нельзя избежать подкачки из-за ограниченного объема доступной оперативной памяти (32 МБ).

Большую часть времени маршрутизатор ничего не делает, однако время от времени осуществляется доступ к базе данных postgresql, также работающей на маршрутизаторе. Из-за того, что tor постоянно работает, postgresql полностью заменяется, и первые несколько обращений имеют очень большую задержку, что плохо, потому что это интерактивно используемая система.

Я уже присвоил значение -15 для postgres и +15 для tor, но, похоже, это не сильно влияет на управление памятью. Глобальная установка swappiness=1 тоже ничего не меняет, потому что свопинга нельзя избежать, а поскольку postgresql большую часть времени не работает, он все равно выгружается.

Есть ли способ что-то вроде приоритета памяти для процесса Linux? Я просмотрел своппинг, специфичный для cgroup, однако единственное описание, которое я нашел, заключалось в том, что он влияет на выбор между кэшем страницы и свопом.

То, что я ищу, - это параметр, чтобы указать ядру Linux не заменять postgresql так агрессивно, как другие процессы (но я не хочу блокировать весь процесс). Или назначение swappiness = 80 для всей системы и swapiness = 1 для postgresql будет держать postgresql в памяти, а все остальное заменять при необходимости?


person user2923748    schedule 20.08.2014    source источник


Ответы (3)


Строго говоря, в Linux вы не можете предотвратить замену процесса. Вы можете избежать полной замены, используя swapoff -a (и добавив немного оперативной памяти), но это может привести к нестабильности системы.

Но в этом случае Linux делает хорошую работу: используемый «время от времени» процесс должен быть выгружен, независимо от того, сколько у вас свободной оперативной памяти. Возможно, вы используете неправильную конфигурацию. Можете ли вы поставить postgres на другой хост, может быть, с более быстрым жестким диском?

Кстати: если вы хотите предотвратить подкачку процесса postgres в вашей текущей конфигурации, я думаю, что вы можете попробовать использовать что-то вроде поддержания активности: пусть демон (или простой скрипт bash) периодически отправляет некоторый запрос, чтобы позволить система видит, что процесс активен.

т.е. вы можете сделать что-то вроде:

#!/bin/bash
DBHOST=localhost
DBPORT=5432
DBNAME=theDBname
DBUSER=theUserName
THEQUERY="SELECT 1"

psql -h $DBHOST -p $DBPORT -d $DBNAME -U $DBUSER  -c "$THEQUERY"

И пусть cron вызывает это каждую минуту или около того.

Если вы хотите что-то более сложное, вы можете создать демон для отправки какого-нибудь «реального» запроса и кэширования результатов, чтобы postgres мог поменять местами, пока у вас уже есть кешированные результаты.

person Stefano Falsetto    schedule 20.08.2014
comment
› Строго говоря, в Linux вы не можете предотвратить выгрузку процесса......Вы можете просто вызвать mlock с правильными параметрами, и процесс будет закреплен в памяти. Спасибо за идею демона - это то, что я сейчас делаю, заставляя postgres периодически меняться местами. Чего я хотел бы добиться, так это того, что postgresql заменяется с более низким приоритетом, чем другие процессы. - person user2923748; 20.08.2014
comment
Да, вы можете использовать mlock, но в этом случае вы должны изменить исходный код postgres, а это не так просто. - person Stefano Falsetto; 20.08.2014

Я думаю, что вам следует настроить PostgreSQL на использование меньшего количества памяти. Он использует большой объем памяти в попытке повысить производительность, но в вашем случае это не работает. Конфигурация по умолчанию для вашей установки OpenWRT PostgreSQL, по-видимому, уже уменьшила объем памяти по сравнению с огромными обычными значениями по умолчанию, но похоже, что вам нужно пойти дальше.

В документации PostgreSQL перечислены параметры, влияющие на его использование ресурса.

Если другие предложения StefanoF и Basile Starynkevitch либо перенести сервер PostgreSQL на другую машину, либо использовать более эффективную базу данных, такую ​​​​как sqlite, являются лучшими решениями, чем попытки улучшить производительность обмена с абсолютно ужасной до просто ужасной.

person Ross Ridge    schedule 20.08.2014

Вы можете использовать mlock(2) и, что более вероятно, madvise(2) внутри вашей программы (вероятно, Postgresql).

Однако я считаю, что Postgresql (или Mysql) слишком велик для системы с 32 МБ ОЗУ. Рассматривали ли вы sqlite? Это библиотека (не сервер), которую вы можете связать со своим приложением, и с ее помощью вы можете выполнять SQL-запросы к локальному файлу sqlite (действующему как база данных). Конечно, вам может понадобиться сделать так, чтобы ваше приложение могло взаимодействовать через Интернет (например, с FASTCGI или с какой-либо библиотекой HTTP-сервера, такой как либонион).

Возможно, ionice(1) может иметь значение (но я думаю, что нет ).

person Basile Starynkevitch    schedule 20.08.2014
comment
что вы подразумеваете под sqlite? насколько я знаю, sqlite не запускает демон и не обслуживает tcp/ip. - person 把友情留在无盐; 23.04.2015