Вопрос или проблема
У меня есть mysql под в моем кластере k8s, вот yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql9
spec:
selector:
matchLabels:
app: mysql9
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql9
spec:
containers:
- image: mysql:8
name: mysql
resources:
limits:
cpu: '2000m'
memory: '12000Mi'
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: mysql-secret
key: username
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: mysql-secret
key: database
- name: MYSQL_ALLOW_EMPTY_PASSWORD
value: 'false'
- name: MYSQL_ONETIME_PASSWORD
value: 'false'
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql9-pv-volume
mountPath: /var/lib/mysql
- name: mysql9-config
mountPath: /etc/mysql/conf.d
volumes:
- name: mysql9-pv-volume
persistentVolumeClaim:
claimName: mysql9-pv-claim
- name: mysql9-config
configMap:
name: mysql9-config
Подключенный конфиг выглядит так:
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql9-config
data:
my.cnf: |
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
[mysqld]
user = mysql
port = 3306
socket = /var/lib/mysql/mysql.sock
mysql_native_password=ON
# Основные настройки
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
pid-file = /var/run/mysqld/mysqld.pid
# log_error = /var/log/mysql/error.log
# Производительность сервера
skip-name-resolve
max_connections = 3000
table_open_cache = 4000
table_open_cache_instances = 8
thread_cache_size = 50
# Настройки памяти
innodb_buffer_pool_size = 9G
innodb_buffer_pool_instances = 9
innodb_log_file_size = 2G # Настройте это в зависимости от ваших потребностей в журнале транзакций
innodb_log_buffer_size = 64M
innodb_file_per_table = 1
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit = 1
innodb_thread_concurrency = 16
innodb_read_io_threads = 8
innodb_write_io_threads = 8
innodb_io_capacity = 250
innodb_io_capacity_max = 500
innodb_purge_threads = 4
# Кэширование и ввод/вывод
# query_cache_type = 0
# query_cache_size = 0
tmp_table_size = 256M
max_heap_table_size = 256M
# join_buffer_size = 16M
# sort_buffer_size = 4M
# read_buffer_size = 4M
# read_rnd_buffer_size = 8M
# Набор символов и сортировка
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
# Двоичное логирование - Рекомендуется для репликации и восстановления в определенный момент времени
# log_bin = /var/log/mysql/mysql-bin.log
# expire_logs_days = 7
# sync_binlog = 1
# binlog_format = ROW
# Настройки журнала ошибок
# log_error_verbosity = 3
# Безопасность
max_allowed_packet = 64M
sql_mode = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
innodb_strict_mode = 1
# Дополнительные настройки
performance_schema = ON
event_scheduler = ON
default_storage_engine = InnoDB
# Настройка режима блокировки автинкремента InnoDB
innodb_autoinc_lock_mode = 2
[mysqldump]
quick
quote-names
[mysql]
no-auto-rehash
И даже несмотря на то, что я установил innodb_buffer_pool_size на 9 ГБ и лимиты ресурсов на 12 ГБ, он почему-то исчерпал память. Как это возможно? Что могло занять еще 3 ГБ и что мне следует изменить, чтобы этого не произошло в будущем?
Вероятно, он запрашивает больше памяти, чем разрешено. Вам следует настроить лимиты для пода, чтобы они соответствовали тому, что вы говорите MySQL использовать, и возможно задать умолчания для вашего пространства имен.
max_connections = 3000
— измените на 300
Если этого недостаточно, измените innodb_buffer_pool_size = 9G
на 8G.
Если оба этих решения не помогут, предоставьте информацию в https://mysql.rjweb.org/doc.php/mysql_analysis#tuning для дальнейшего анализа.
Ответ или решение
Ваша проблема, связанная с тем, что MySQL в Kubernetes кластере выдает ошибку "Out of Memory", несмотря на наличие достаточно большой оперативной памяти, может иметь несколько причин. Варианты устранения неполадок и оптимизации можно рассмотреть следующим образом:
-
Проверка настройки лимитов ресурсов:
Убедитесь, что лимиты ресурсов, установленные для вашего Pod, соответствуют настройкам MySQL. В вашем манифесте Pod вы установили лимиты на виртуальные CPU и память (12GB), но MySQL может запросить больше памяти, чем вы указали. Широкие значения, как напримерmax_connections = 3000
, могут потребовать значительно большее количество памяти. -
Настройки
max_connections
:
Я рекомендую вам изменить настройкуmax_connections
на более разумное значение, например, с 3000 на 300. Каждое соединение требует определенного количества памяти, и если у вас активны множество соединений, это может привести к превышению лимита ресурсов Pod и, как следствие, к аварийному завершению работы MySQL. -
Корректировка
innodb_buffer_pool_size
:
Установитеinnodb_buffer_pool_size
на 8GB вместо 9GB. Несмотря на то, что вы выделили 12GB, в Kubernetes есть дополнительные накладные расходы на другие процессы приложения, которые также могут потреблять память. В данном случае, можно оставить слот для других компонентов и системных процессов. -
Дополнительные параметры конфигурации:
Проверьте другие параметры, которые могут потреблять память, такие какtmp_table_size
,max_heap_table_size
, и другие буферные настройки. Убедитесь, что они соответствуют реальным потребностям вашей базы данных и доступны в пределах выделенной памяти. -
Мониторинг и анализ:
Вам следует периодически мониторить использование памяти в вашем MySQL и Kubernetes кластере для выявления потенциальных утечек памяти или ненормального поведения. Используйте такие инструменты, как Prometheus и Grafana для мониторинга, что даст вам четкое представление о состоянии системы. -
Настройки по умолчанию для кластера:
Если вы хотите оптимизировать использование памяти для всех Pod в вашем namespace, рассмотрите возможность установки настройки по умолчанию для ресурсов.
Если после всех изменений проблемы с памятью все еще появляются, можно изучить подробные отчеты по производительности и специальные инструменты анализа, чтобы лучше понять, какие части вашего приложения потребляют больше ресурсов, чем ожидалось. Вы можете начать с данной страницы для более детального анализа.
Эти изменения и мониторинг в будущем должны помочь избежать проблем с исчерпанием памяти и обеспечить стабильную работу вашего MySQL в Kubernetes.