Redis Enterprise étend l’évolutivité linéaire avec 200 millions d’opérations/sec @

Redis Enterprise étend l’évolutivité linéaire avec 200 millions d’opérations/sec @

Toutes les applications grand public modernes doivent évoluer facilement et de manière rentable, et pour cela, les performances de base de données linéaires sont essentielles. Avec notre architecture sans partage, nous avons prouvé à maintes reprises qu’un seul cluster Redis Enterprise peut évoluer à l’infini de manière linéaire en ajoutant simplement des fragments et des nœuds. Mais cela ne veut pas dire que nous nous reposons sur nos lauriers. Lors de RedisConf18, nous avons démontré qu’un seul cluster Redis Enterprise pouvait atteindre 50 millions d’opérations par seconde (ops/sec) avec seulement 26 instances AWS tout en gardant une latence inférieure à 1 milliseconde, et aujourd’hui, nous sommes heureux de partager que Redis Enterprise a établi un nouveau record de performance dans l’industrie.

Dans notre dernier benchmark, Redis Enterprise a fourni plus de 200 millions d’opérations/sec, avec une latence inférieure à 1 milliseconde, sur aussi peu que 40 instances AWS. Cela représente une amélioration des performances de 2,6 fois en moins de 15 mois. Avant d’aborder la configuration, les outils, les charges de travail et les résultats de notre dernier benchmark, passons rapidement en revue les clusters Redis Enterprise.

Remise à niveau de l’architecture d’entreprise Redis

En termes Redis Enterprise, un cluster est un ensemble de nœuds composés d’instances cloud, de machines virtuelles ou de conteneurs/POD Kubernetes, ou de serveurs bare metal. Un cluster vous permet de créer des bases de données Redis dans un pool de mémoire partagé entre ces nœuds, tout en maintenant une séparation complète entre le chemin des données et le chemin de contrôle et de gestion. Chaque cluster comprend des fragments Redis, un proxy sans latence et un gestionnaire de cluster. Étant donné que l’API de cluster open source permet aux clients Redis d’accéder directement au fragment contenant l’objet clé-valeur sans saut de réseau supplémentaire, un cluster Redis Enterprise peut évoluer très efficacement. Le chemin de contrôle (qui traite du provisionnement/déprovisionnement de la base de données, du basculement automatique, de la migration des partitions, de l’équilibrage des clusters et bien plus encore) impose très peu de surcharge et n’affecte pas cette évolutivité linéaire. Enfin et surtout, Redis Enterprise utilise efficacement tous les cœurs de chaque nœud de cluster avant d’ajouter d’autres nœuds au cluster à des fins de mise à l’échelle.

Voici une représentation visuelle de l’architecture de cluster sans partage de Redis Enterprise, configurée avec l’API de cluster open source et utilisant tous les cœurs d’un nœud de cluster donné :

blog volkov 20190625 1 v5

Référence de nœud unique

Comme référence, nous voulions tester le nombre d’opérations/sec que nous pouvions atteindre lors de l’exécution sur une seule instance AWS, et en gardant à l’esprit les exigences suivantes :

  • Maintenir une latence inférieure à 1 msec
  • Gardez notre pipeline à 9 max
  • Utiliser une taille de valeur de 100 octets
  • Avoir un ratio Get:Set de 1:1

Pour ce faire, nous avons utilisé la configuration système suivante:

1) Nous avons installé Redis Enterprise.
https://docs.redis.com/latest/rs/installing-upgrading/downloading-installing/

2) Nous avons configuré Route53.
https://docs.redis.com/latest/rs/installing-upgrading/configuring/cluster-name-dns-connection-management/configuring-aws-route53-dns-redis-enterprise/

3) Nous avons créé notre base de données.
Spécifier cluster_api_user, Nom, shards_count et Port

Comme indiqué ci-dessous, l’API créera une base de données nom : avec partitions : écoute sur port :. Même si nous avons utilisé un cluster à nœud unique pour ce benchmark, nous avons également défini le proxy_policy, shards_placement et oss_cluster paramètres. Ceux-ci sont utilisés pour placer les fragments de manière égale et créer des points de terminaison sur tous les nœuds, afin de rester cohérent avec la configuration du cluster à plusieurs nœuds.

curl -v -k -u <cluster_api_user> https://localhost:9443/v1/bdbs -H "Content-type: application/json" -d
'{
"name": <name>,
"memory_size": 10000000000,
"type" : "redis",
"sharding": true ,
"shards_count": <shards_count>,
"shard_key_regex": [{"regex": ".*{(?<tag>.*)}.*"},{"regex": "(?<tag>.*)" }],
"proxy_policy": "all-master-shards",
"shards_placement": "sparse",
"oss_cluster":true,
"port":<port>
}'

Pour s’assurer que le test était équitable, nous avons d’abord rempli la base de données pour éviter les opérations GET sur des clés inexistantes (spécifiez NUM_OF_KEYS):

memtier_benchmark  -s <EndPoint> -p <Port> -t 48 --ratio=1:0 --pipeline=9 -c 1 -d 100 --key-minimum=1  --key-maximum=<NUM_OF_KEYS> -n allkeys --key-pattern=S:S

4) Nous avons choisi le type d’instance c5.18xlarge sur AWS EC2 pour notre nœud, avec 72 vCPU 144 Go et un processeur Intel Xeon Skylake-SP de 3,0 GHz (jusqu’à 3,5 GHz avec la technologie Intel Turbo Boost).

5) Nous avons choisi un type d’instance c5.9xlarge pour exécuter l’outil de génération de charge pour notre machine cliente.

6) Enfin, pour notre outil de génération de charge, nous avons utilisé memtier_benchmark avec les paramètres suivants :

memtier_benchmark -s <redis.endpoint.address> -p <port> -t $Threads —ratio=1:1 --pipeline=9 -c $Clients -d 100 --key-minimum=1  --key-maximum=<NUMBER_OF_KEYS> -n 1000000000 --cluster-mode 

Nous avons ensuite essayé de trouver le meilleur équilibre entre les fragments et les threads proxy, et avons observé que nos meilleurs résultats étaient obtenus avec 8 fragments par nœud, ce qui nous donnait 4,2 millions d’opérations/sec. Le débit était instable, en raison du changement de contexte des threads proxy et des transitions de processus Redis entre les processeurs sur différents nœuds NUMA. Cet accès inter-mémoire a augmenté la latence de traitement, même si le système n’était chargé qu’à 50 %.

Comme le montre l’image ci-dessous, nous avons pu obtenir de bien meilleurs résultats avec des configurations à 8 et 10 fragments sur l’instance c5.18xlarge, en utilisant la liaison NUMA pour l’affinité des fragments Redis et des threads proxy :

blog volkov 20190625 2

Remarque : Les scripts ci-dessous fonctionnent uniquement sur les systèmes à deux sockets.

  • Paramètre threads proxy équilibrant entre les nœuds numa :

NUMA_CNT=$(numactl --hardware | grep '^available' | awk '{print $2}')
if [ $NUMA_CNT -eq 2 ]; then
  NODE_ID=$(cat /etc/opt/redis/node.id)
  DMC_HALF_COUNT=$(expr $(/opt/redis/bin/ccs-cli hget dmc:$NODE_ID threads) / 2)
  NUMA0_CPUS=$(numactl  --hardware | grep 'node 0 cpus' | awk -F ': ' '{print $2}' | sed 's/ /,/g')
  NUMA1_CPUS=$(numactl  --hardware | grep 'node 1 cpus' | awk -F ': ' '{print $2}' | sed 's/ /,/g')
  DMC_PID=$(sudo /opt/redis/bin/dmc-cli -ts root list | grep listener | awk '{printf "%in",$3}')
  sudo taskset -apc $NUMA0_CPUS $DMC_PID 
    sudo /opt/redis/bin/dmc-cli -ts root list | grep worker | tail -$DMC_HALF_COUNT |
      awk '{printf "%in",$3}' |
      xargs -i sudo taskset -pc $NUMA1_CPUS {}
fi

  • Équilibrage et liaison du processeur et de la mémoire pour les processus Redis :

NUMA_CNT=$(numactl --hardware | grep '^available' | awk '{print $2}')
REDIS_HALF_CNT=$(expr $(pgrep redis-server-5 | wc -l) / 2)
NUMA0_CPUS=$(numactl  --hardware | grep 'node 0 cpus' | awk -F ': ' '{print $2}' | sed 's/ /,/g')
NUMA1_CPUS=$(numactl  --hardware | grep 'node 1 cpus' | awk -F ': ' '{print $2}' | sed 's/ /,/g')
pgrep redis-server-5 | sort | head -$REDIS_HALF_CNT | xargs -i sudo taskset -apc $NUMA0_CPUS {} &&
  pgrep redis-server-5 | sort | head -$REDIS_HALF_CNT | xargs -i sudo migratepages {} 1 0
pgrep redis-server-5 | sort | tail -$REDIS_HALF_CNT | xargs -i sudo taskset -apc $NUMA1_CPUS {} &&
  pgrep redis-server-5 | sort | tail -$REDIS_HALF_CNT | xargs -i sudo migratepages {} 0 1

Résumé des résultats d’un nœud unique

Le tableau ci-dessous montre comment nous avons déterminé la configuration optimale des fragments Redis et des threads proxy sur l’instance AWS c5.18xlarge afin d’obtenir le meilleur débit possible (en ops/sec) tout en maintenant une latence inférieure à la milliseconde :

Fragments 4 6 8 8 dix
Fils proxy 16 24 28 28 32
Commentaire Défaut Défaut Défaut NUMA à l’écoute NUMA à l’écoute
Latence (ms) 0,92 0,91 0,98 0,81 0,92
Débit
(M ops/s)
2.9 3,89 4.2 4.8 5.3
Débit par partition (K ops/s) 725 648 525 600 530

Mise à l’échelle du cluster

50 millions d’opérations/s avec 10 instances AWS c5.18xlarge

Nous voulions d’abord atteindre le benchmark de 50 millions d’opérations/sec que nous avons démontré lors de RedisConf18 avec 26 instances m4.16xlarge. Cette fois, nous avons pu atteindre 51,72 millions d’opérations/sec avec seulement 10 instances AWS 5.18xlarge :

Nœuds (C5.18xlarge) dix
Clients (C5.9xlarge) dix
Fragments par nœud dix
Fils proxy 32
Clés préremplies 10M
Connexions 14 800
Nombre moyen d’opérations/s 51.72M
Latence moyenne 0,92
Nombre moyen d’opérations/s par nœud 5.17M

blog volkov 20190625 3

blog volkov 20190625 4

Nous sommes ensuite passés à 100 millions d’opérations/s avec 20 instances AWS 5.18xlarge

Nœuds (C5.18xlarge) 20
Clients (C5.9xlarge) 20
Fragments par nœud dix
Fils proxy 32
Clés préremplies 10M
Connexions 30 400
Nombre moyen d’opérations/s 102.37M
Latence moyenne 0,94
Nombre moyen d’opérations/s par nœud 5.11M

blog volkov 20190625 5

blog volkov 20190625 6

blog volkov 20190625 7

Et enfin, 200 millions d’opérations/sec avec 40 instances AWS c5.18xlarge

Nœuds (C5.18xlarge) 40
Clients (C5.9xlarge) 30
Fragments par nœud dix
Fils proxy 32
Clés préremplies 10M
Connexions 72 000
Nombre moyen d’opérations/s 201.17M
Latence moyenne 0,99
Nombre moyen d’opérations/s par nœud 5.02M

blog volkov 20190625 8

blog volkov 20190625 9

blog volkov 20190625 10

Résumé des résultats

blog volkov 20190625 11 v4

Nos multiples améliorations du noyau Redis dans la version 5.0 (en particulier en ce qui concerne les performances des gros pipelines), ainsi que de nombreuses améliorations du proxy Redis Enterprise et de la façon dont il communique avec les fragments Redis, et combinées avec la nouvelle famille d’instances AWS C5 et un bon Configuration NUMA, tous ont aidé à atteindre plus de 200 M opérations/s avec seulement un 40 nœuds cluster tout en maintenant la latence sous 1 milliseconde.

Notre architecture sans partage permet un accès supplémentaire + de 500 000 opérations/s pour chaque partition Redis et + de 5 millions d’opérations/s pour chaque nœud ajouté au cluster, dans une mise à l’échelle linéaire proche de l’optimum de 94 %. En d’autres termes, le débit par nœud n’a diminué que de 6 % entre un nœud unique et un cluster de 40 nœuds.

Au cours de ces tests, nous avons même réussi à atteindre 800 000 opérations/s par partition Redis (avec une latence constante inférieure à la milliseconde), mais en raison des limites de paquets réseau par seconde, nous n’avons pas été en mesure d’adapter le débit de nos nœuds pour obtenir des performances plus élevées et stables dans le temps. .

Nous avons été étonnés par l’amélioration significative que nous avons constatée en battant notre propre record de performances de base de données d’il y a 15 mois :

Mars 2018 Juin 2019 Amélioration
Débit du cluster 50 M opérations/s 200 M opérations/s x4
# de nœuds 26 40 x2.6
# de fragments 512 400 x5

Cette expérience montre qu’avec une architecture appropriée, telle qu’implémentée par Redis Enterprise, Redis peut battre n’importe quel record de performances dans l’espace de la base de données tout en utilisant beaucoup moins de ressources matérielles que les autres bases de données.

Development Source

Related Posts

RLEC 4.2.1 apporte des contrôles granulaires à la haute disponibilité et aux performances

RLEC 4.2.1 apporte des contrôles granulaires à la haute disponibilité et aux performances

Comment HolidayMe utilise Redis Enterprise comme base de données principale

Comment HolidayMe utilise Redis Enterprise comme base de données principale

Annonce de RedisGears 1.0 : un moteur sans serveur pour Redis

Annonce de RedisGears 1.0 : un moteur sans serveur pour Redis

Clés Redis dans la RAM |  Redis

Clés Redis dans la RAM | Redis

No Comment

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *