Commit f10edecb authored by Пальмин Альберт's avatar Пальмин Альберт
Browse files

Merge branch 'Feature#34821' into 'master'

Feature#34821

See merge request !1
1 merge request!1Feature#34821
Showing with 190 additions and 1781 deletions
+190 -1781
# Redis
### Перед установкой важно:
#### 1) Роль протестирована для ubuntu20 и ubuntu22. На ubuntu-18 роль не работает;
#### 2) Убедиться в наличии мастера;
#### 3) Если инсталяций redis & sentinel на ноде нет, мастером по умолчанию становится первый хост из группы redis;
#### 4) Если планируется работа с существующим кластером, правильно будет запускать сначала по одной машине, а затем прогнать все разом.
---
# MAIN REDIS CONFIGUTATION SETTINGS
install_dir: "/opt/"
redis_run_dir: "/var/run/redis"
redis_conf_dir: "/etc/redis"
redis_lib_dir: "/var/lib/redis"
redis_logfile: "/var/log/redis.log"
redis_port: "6379"
sentinel_port: "26379"
redis_bind_loop: 0.0.0.0
redis_requirepass: <your_password_here> #в group_vars прописать пароль
redis_loglevel: "notice"
redis_databases: 4
redis_pid: /var/run/redis/redis-server.pid
redis_dbdir: /var/lib/redis
tcp_backlog: 511
tcp_keepalive: 300
redis_repository: deb [signed-by=/etc/apt/trusted.gpg.d/redis-archive-keyring.gpg] https://packages.redis.io/deb {{ ansible_distribution_release }} main
# Cache or Only or Session-Store options
# Change to 1 for yes or 2 for no | Both values can't be the same
redis_cache: 1
redis_session: 0
redis_version_full: "{{ redis_version }}~{{ ansible_distribution_release }}1" #полная версия redis
redis_version: 6:7.0.5-1rl1 #номер версии
# SENTINEL CONFIGURATION SETTINGS
redis_master_name: redis-node-master
sentinel_deny_scripts_reconfig: yes
protected_mode: yes
supervised_mode: yes # set to yes or no to allow
sentinel_pid: /var/run/redis-sentinel.pid
sentinel_logfile: /var/log/redis-sentinel.log
sentinel_pid: /var/run/sentinel/redis-sentinel.pid
sentinel_logfile: /var/log/redis/redis-sentinel.log
sentinel_quorum: 2
sentinel_down_ms: 2000
sentinel_down_ms: 3000
sentinel_failtime: 3000
# REDIS.CONF SETTINGS
redis_daemon: redis
redis_unixsocket:
redis_timeout: 0
redis_loglevel: "notice"
redis_databases: 16
redis_rdbcompression: "yes"
redis_dbfilename: dump.rdb
redis_dbdir: /var/lib/redis
tcp_backlog: 511
tcp_keepalive: 300
daemonize: yes
supervised: 1
cache_maxmemory_policy: "allkeys-lru"
redis_save:
- 900 1
- 300 10
- 60 10000
session_maxmemory_policy: "noeviction"
---
- name: restart redis
service: "name={{ redis_daemon }} state=restarted"
galaxy_info:
role_name: cloudteam.redis
author: Efimovsy (krylovia@cloud-team.ru)
description: Basic role for redis-sentinel
author: palminas@cloud-team.ru
description: Basic role for redis-server & redis-sentinel
company: CloudTeam
license: BSD
dependencies: []
---
- set_fact: #Выбор первого хоста из группы redis если это первая установка
redis_master: "{{ groups['redis'] | map('extract', hostvars,['ansible_host']) | first }}"
- import_tasks: install.yml #Установка redis-server & redis-sentinel
- import_tasks: systemd.yml #Установка службы
- import_tasks: config-redis.yml #Конфигурирование redis
- import_tasks: config-sentinel.yml #Конфигурирование sentinel
---
- block:
- name: Copy Redis template for master #Конфиг для мастера
template:
src: "master-conf.j2"
dest: "/etc/redis/redis.conf"
mode: 0644
register: redis_master_changed
- name: Restart redis-server for master #Необходимо перезагружать принудительно только если конфиг поменялся
ansible.builtin.systemd:
state: restarted
name: redis-server
when: redis_master_changed.changed
when: ansible_host == redis_master
- block:
- name: Copy Redis template for slave #Конфиг для слейвов
template:
src: "slave-conf.j2"
dest: "/etc/redis/redis.conf"
mode: 0644
register: redis_slave_changed
- name: Restart redis-server for slave #Необходимо перезагружать принудительно только если конфиг поменялся
ansible.builtin.systemd:
state: restarted
name: redis-server
when: redis_slave_changed.changed
when: ansible_host != redis_master
---
- name: Copy Sentinel template #Общий конфиг сентинела для всех
template:
src: "sentinel.j2"
dest: "/etc/redis/sentinel.conf"
mode: 0644
- name: Restart redis-sentinel #Необходимо перезагружать принудительно
ansible.builtin.systemd:
state: restarted
name: redis-sentinel
---
- import_tasks: systemd.yml
- name: Definition master #Определение мастера
shell: |
redis-cli -a {{ redis_requirepass }} -p {{ sentinel_port }} SENTINEL \
get-master-addr-by-name {{ redis_master_name }} | grep -E "([0-9]\.)+"
register: var_master
args:
executable: /bin/bash
- set_fact:
redis_master: "{{ var_master.stdout }}"
- import_tasks: config-redis.yml
- import_tasks: config-sentinel.yml
---
- name: check key exist
stat:
path: /etc/apt/trusted.gpg.d/redis-archive-keyring.gpg
register: stat_result
- name: download GPG
get_url:
url: https://packages.redis.io/gpg
dest: ~/gpg
when: not stat_result.stat.exists
- name: add pgp key
shell: |
cat ~/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg &&\
cp /usr/share/keyrings/redis-archive-keyring.gpg /etc/apt/trusted.gpg.d/
when: not stat_result.stat.exists
- name: add apt repository redis
become: yes
apt_repository:
repo: '{{ redis_repository }}'
filename: redis
- name: Install redis-server & redis-sentinel
apt:
name: "{{item}}"
state: present
update_cache: yes
cache_valid_time: 3600
loop:
- redis-server={{ redis_version_full }}
- redis-sentinel={{ redis_version_full }}
---
- set_fact:
redis_master: "{{ groups['master'] | map('extract', hostvars, ['ansible_host']) | join(',') }}"
- block: #=====Block for ubuntu-20, ubuntu-22=====
- name: check key exist
stat:
path: /etc/apt/trusted.gpg.d/redis-archive-keyring.gpg
register: stat_result
- name: Query packages #Запрос пакетов из дистрибутива
ansible.builtin.package_facts:
manager: auto
- name: download GPG
get_url:
url: https://packages.redis.io/gpg
dest: gpg
when: not stat_result.stat.exists
- name: add pgp key
shell: |
cat gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg &&\
cp /usr/share/keyrings/redis-archive-keyring.gpg /etc/apt/trusted.gpg.d/
when: not stat_result.stat.exists
- name: add apt repository redis
become: yes
apt_repository:
repo: '{{ redis_repository }}'
filename: redis
- name: "Install redis & redis-sentinel"
become: yes
apt:
name: 'redis-sentinel,redis-server'
state: present
update_cache: yes
- name: Setup Redis Systemd
template:
src: systemd-redis.j2
dest: "/etc/systemd/system/redis-server.service"
mode: 0644
become: true
- name: Setup Redis Sentinel Systemd
template:
src: systemd-sentinel.j2
dest: "/etc/systemd/system/redis-sentinel.service"
mode: 0644
become: true
- name: Reload systemd
systemd:
daemon_reload: yes
become: true
- name: Copy Redis template
template:
src: "{{ redis_role }}-conf.j2"
dest: "/etc/redis/redis.conf"
mode: 0644
become: true
- name: Copy Sentinel template
template:
src: "sentinel.j2"
dest: "/etc/redis/sentinel.conf"
mode: 0644
become: true
- name: Ensure Redis is is started on runtime
systemd:
name: redis-server
enabled: yes
become: true
- name: Ensure Redis is is started on runtime
systemd:
name: redis-sentinel
enabled: yes
become: true
- name: Restart Redis
systemd:
name: redis-server
state: restarted
become: true
- name: Restart Redis Sentinel
systemd:
name: redis-sentinel
state: restarted
become: true
- import_tasks: current.yml #Если redis & sentinel установлены. Текущий мастер не затрагивается
when: "'redis-server' in ansible_facts.packages and 'redis-sentinel' in ansible_facts.packages"
- import_tasks: begin.yml #Если redis & sentinel не установлены. Мастером будет первая нода из инвентаря
when: "'redis-server' not in ansible_facts.packages and 'redis-sentinel' not in ansible_facts.packages"
when: ansible_distribution_release == 'focal' or ansible_distribution_release == 'jammy'
---
- name: Setup Redis Systemd
template:
src: systemd-redis.j2
dest: "/etc/systemd/system/redis-server.service"
mode: 0644
- name: Setup Redis Sentinel Systemd
template:
src: systemd-sentinel.j2
dest: "/etc/systemd/system/redis-sentinel.service"
mode: 0644
- name: Reload systemd
systemd:
daemon_reload: yes
- name: Enable & start redis-server
ansible.builtin.systemd:
name: redis-server
state: started
enabled: yes
- name: Enable & start redis-sentinel
ansible.builtin.systemd:
name: redis-sentinel
state: started
enabled: yes
This diff is collapsed.
# Example sentinel.conf
# *** IMPORTANT ***
#
# By default Sentinel will not be reachable from interfaces different than
# localhost, either use the 'bind' directive to bind to a list of network
# interfaces, or disable protected mode with "protected-mode no" by
# adding it to this configuration file.
#
# Before doing that MAKE SURE the instance is protected from the outside
# world via firewalling or other means.
#
# For example you may use one of the following:
#
# bind 127.0.0.1 192.168.1.1
#
# protected-mode no
# port <sentinel-port>
# The port that this sentinel instance will run on
port 26379
# By default Redis Sentinel does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis-sentinel.pid when
# daemonized.
daemonize no
# When running daemonized, Redis Sentinel writes a pid file in
# /var/run/redis-sentinel.pid by default. You can specify a custom pid file
# location here.
pidfile /var/run/redis-sentinel.pid
# Specify the log file name. Also the empty string can be used to force
# Sentinel to log on the standard output. Note that if you use standard
# output for logging but daemonize, logs will be sent to /dev/null
logfile ""
# sentinel announce-ip <ip>
# sentinel announce-port <port>
#
# The above two configuration directives are useful in environments where,
# because of NAT, Sentinel is reachable from outside via a non-local address.
#
# When announce-ip is provided, the Sentinel will claim the specified IP address
# in HELLO messages used to gossip its presence, instead of auto-detecting the
# local address as it usually does.
#
# Similarly when announce-port is provided and is valid and non-zero, Sentinel
# will announce the specified TCP port.
#
# The two options don't need to be used together, if only announce-ip is
# provided, the Sentinel will announce the specified IP and the server port
# as specified by the "port" option. If only announce-port is provided, the
# Sentinel will announce the auto-detected local IP and the specified port.
#
# Example:
#
# sentinel announce-ip 1.2.3.4
# dir <working-directory>
# Every long running process should have a well-defined working directory.
# For Redis Sentinel to chdir to /tmp at startup is the simplest thing
# for the process to don't interfere with administrative tasks such as
# unmounting filesystems.
dir /tmp
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
#
# Tells Sentinel to monitor this master, and to consider it in O_DOWN
# (Objectively Down) state only if at least <quorum> sentinels agree.
#
# Note that whatever is the ODOWN quorum, a Sentinel will require to
# be elected by the majority of the known Sentinels in order to
# start a failover, so no failover can be performed in minority.
#
# Replicas are auto-discovered, so you don't need to specify replicas in
# any way. Sentinel itself will rewrite this configuration file adding
# the replicas using additional configuration options.
# Also note that the configuration file is rewritten when a
# replica is promoted to master.
#
# Note: master name should not include special characters or spaces.
# The valid charset is A-z 0-9 and the three characters ".-_".
sentinel monitor mymaster 127.0.0.1 6379 2
# sentinel auth-pass <master-name> <password>
#
# Set the password to use to authenticate with the master and replicas.
# Useful if there is a password set in the Redis instances to monitor.
#
# Note that the master password is also used for replicas, so it is not
# possible to set a different password in masters and replicas instances
# if you want to be able to monitor these instances with Sentinel.
#
# However you can have Redis instances without the authentication enabled
# mixed with Redis instances requiring the authentication (as long as the
# password set is the same for all the instances requiring the password) as
# the AUTH command will have no effect in Redis instances with authentication
# switched off.
#
# Example:
#
# sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
# sentinel down-after-milliseconds <master-name> <milliseconds>
#
# Number of milliseconds the master (or any attached replica or sentinel) should
# be unreachable (as in, not acceptable reply to PING, continuously, for the
# specified period) in order to consider it in S_DOWN state (Subjectively
# Down).
#
# Default is 30 seconds.
sentinel down-after-milliseconds mymaster 30000
# sentinel parallel-syncs <master-name> <numreplicas>
#
# How many replicas we can reconfigure to point to the new replica simultaneously
# during the failover. Use a low number if you use the replicas to serve query
# to avoid that all the replicas will be unreachable at about the same
# time while performing the synchronization with the master.
sentinel parallel-syncs mymaster 1
# sentinel failover-timeout <master-name> <milliseconds>
#
# Specifies the failover timeout in milliseconds. It is used in many ways:
#
# - The time needed to re-start a failover after a previous failover was
# already tried against the same master by a given Sentinel, is two
# times the failover timeout.
#
# - The time needed for a replica replicating to a wrong master according
# to a Sentinel current configuration, to be forced to replicate
# with the right master, is exactly the failover timeout (counting since
# the moment a Sentinel detected the misconfiguration).
#
# - The time needed to cancel a failover that is already in progress but
# did not produced any configuration change (SLAVEOF NO ONE yet not
# acknowledged by the promoted replica).
#
# - The maximum time a failover in progress waits for all the replicas to be
# reconfigured as replicas of the new master. However even after this time
# the replicas will be reconfigured by the Sentinels anyway, but not with
# the exact parallel-syncs progression as specified.
#
# Default is 3 minutes.
sentinel failover-timeout mymaster 180000
# SCRIPTS EXECUTION
#
# sentinel notification-script and sentinel reconfig-script are used in order
# to configure scripts that are called to notify the system administrator
# or to reconfigure clients after a failover. The scripts are executed
# with the following rules for error handling:
#
# If script exits with "1" the execution is retried later (up to a maximum
# number of times currently set to 10).
#
# If script exits with "2" (or an higher value) the script execution is
# not retried.
#
# If script terminates because it receives a signal the behavior is the same
# as exit code 1.
#
# A script has a maximum running time of 60 seconds. After this limit is
# reached the script is terminated with a SIGKILL and the execution retried.
# NOTIFICATION SCRIPT
#
# sentinel notification-script <master-name> <script-path>
#
# Call the specified notification script for any sentinel event that is
# generated in the WARNING level (for instance -sdown, -odown, and so forth).
# This script should notify the system administrator via email, SMS, or any
# other messaging system, that there is something wrong with the monitored
# Redis systems.
#
# The script is called with just two arguments: the first is the event type
# and the second the event description.
#
# The script must exist and be executable in order for sentinel to start if
# this option is provided.
#
# Example:
#
# sentinel notification-script mymaster /var/redis/notify.sh
# CLIENTS RECONFIGURATION SCRIPT
#
# sentinel client-reconfig-script <master-name> <script-path>
#
# When the master changed because of a failover a script can be called in
# order to perform application-specific tasks to notify the clients that the
# configuration has changed and the master is at a different address.
#
# The following arguments are passed to the script:
#
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
#
# <state> is currently always "failover"
# <role> is either "leader" or "observer"
#
# The arguments from-ip, from-port, to-ip, to-port are used to communicate
# the old address of the master and the new address of the elected replica
# (now a master).
#
# This script should be resistant to multiple invocations.
#
# Example:
#
# sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
# SECURITY
#
# By default SENTINEL SET will not be able to change the notification-script
# and client-reconfig-script at runtime. This avoids a trivial security issue
# where clients can set the script to anything and trigger a failover in order
# to get the program executed.
sentinel deny-scripts-reconfig yes
# REDIS COMMANDS RENAMING
#
# Sometimes the Redis server has certain commands, that are needed for Sentinel
# to work correctly, renamed to unguessable strings. This is often the case
# of CONFIG and SLAVEOF in the context of providers that provide Redis as
# a service, and don't want the customers to reconfigure the instances outside
# of the administration console.
#
# In such case it is possible to tell Sentinel to use different command names
# instead of the normal ones. For example if the master "mymaster", and the
# associated replicas, have "CONFIG" all renamed to "GUESSME", I could use:
#
# SENTINEL rename-command mymaster CONFIG GUESSME
#
# After such configuration is set, every time Sentinel would use CONFIG it will
# use GUESSME instead. Note that there is no actual need to respect the command
# case, so writing "config guessme" is the same in the example above.
#
# SENTINEL SET can also be used in order to perform this configuration at runtime.
#
# In order to set a command back to its original name (undo the renaming), it
# is possible to just rename a command to itsef:
#
# SENTINEL rename-command mymaster CONFIG CONFIG
# {{ ansible_managed }}
bind 0.0.0.0
bind {{ redis_bind_loop }}
port 6379
tcp-backlog 511
tcp-keepalive 0
tcp-keepalive {{ tcp_keepalive }}
timeout 0
daemonize no
supervised systemd
tcp-backlog 511
pidfile /var/run/redis/redis.pid
loglevel notice
pidfile {{ redis_pid }}
loglevel {{ redis_loglevel }}
logfile /var/log/redis/redis-server.log
dir "/var/lib/redis"
always-show-logo yes
databases 4
databases {{ redis_databases }}
save 900 1
save 300 10
save 60 10000
# Snapshotting
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
rdb-del-sync-files no
dbfilename "dump.rdb"
# Replication
......@@ -70,23 +72,19 @@ aof-rewrite-incremental-fsync yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
aof-load-truncated yes
aof-use-rdb-preamble yes
latency-monitor-threshold 0
dynamic-hz yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
{% if redis_requirepass %}
requirepass {{ redis_requirepass }}
masterauth {{ redis_requirepass }}
{% endif %}
\ No newline at end of file
{% endif %}
......@@ -3,10 +3,10 @@ daemonize no
supervised systemd
dir {{ redis_dbdir }}
pidfile {{ sentinel_pid }}
logfile /var/log/redis/redis-sentinel.log
logfile {{ sentinel_logfile }}
protected-mode no
bind 0.0.0.0
bind {{ redis_bind_loop }}
port {{ sentinel_port }}
sentinel deny-scripts-reconfig yes
sentinel monitor {{ redis_master_name }} {{ redis_master }} {{ redis_port }} {{ sentinel_quorum }}
......@@ -20,6 +20,4 @@ sentinel auth-pass {{ redis_master_name }} {{ redis_requirepass }}
{% endif %}
# Generated by CONFIG REWRITE
# {{ ansible_managed }}
bind 0.0.0.0
bind {{ redis_bind_loop }}
port 6379
tcp-backlog 511
tcp-keepalive 0
tcp-keepalive {{ tcp_keepalive }}
timeout 0
daemonize no
supervised systemd
tcp-backlog 511
pidfile /var/run/redis/redis.pid
loglevel notice
pidfile {{ redis_pid }}
loglevel {{ redis_loglevel }}
logfile /var/log/redis/redis-server.log
dir "/var/lib/redis"
always-show-logo yes
databases 4
databases {{ redis_databases }}
save 900 1
save 300 10
save 60 10000
# Snapshotting
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
rdb-del-sync-files no
dbfilename "dump.rdb"
# Replication
......@@ -70,31 +72,23 @@ aof-rewrite-incremental-fsync yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
aof-load-truncated yes
aof-use-rdb-preamble yes
latency-monitor-threshold 0
dynamic-hz yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
{% if redis_requirepass %}
requirepass {{ redis_requirepass }}
masterauth {{ redis_requirepass }}
{% endif %}
# Replication settings
{% for host in groups['slave'] %}
{% if hostvars[host]['redis_role'] == 'slave' %}
replicaof {{redis_master}} {{ redis_port }}
{% endif %}
{% endfor %}
replicaof {{ redis_master }} {{ redis_port }}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment