SlideShare une entreprise Scribd logo
1  sur  45
Télécharger pour lire hors ligne
ProxySQL at Scale on AWS
Percona Live 2022
Challenges
● Over 100 diverse backend types, 400+ EC2 instances
○ Different query routing
○ Different users and configurations
● Cloud environment
○ Short lived instances
○ Shorter lifetime
● Disposable infrastructure
○ Configuration drift
○ History of changes
Three level provisioning
● AWS resources
○ Load balancer
○ Auto Scaling Group
○ CNAME
● Zero downtime
migrations
● OS level
● Packages
● Configs
● Services
● Config Agent
○ ProxySQL final
configuration
○ Updating configs
○ Restarts
● Healthchecks
○ Flexible logic
Guiding principles
● Infrastructure as code
○ Git as UI
● Declarative is favored over imperative
● Terraform - one time change
● Puppet - rare changes
● Python - frequent changes
ProxySQL Unit
P
ASG
N
N
N
Load Balancer
AZ1
AZ2
AZ3
P
P
P
P
P
to provision
Terraform
Example: Terraform
module "sandboxdb" {
source = "git::ssh://git@p.com/terraform-aws-proxysql.git?ref=4.0.0"
security_group_ids = [
data.aws_security_group.proxysql["vpc-db-automation"].id,
data.aws_security_group.proxysql["proxysql_use1_healthcheck"].id,
data.aws_security_group.proxysql["proxysql_data"].id,
data.aws_security_group.proxysql["vpc-dev-data-layer"].id
]
iam_instance_profile = data.aws_iam_instance_profile.proxysql.arn
aws_ami = var.aws_ami_map["default"]
subnets = var.subnets
backend_type = "sandboxdb"
enable_deletion_protection = false
health_check_type = "EC2"
health_check_grace_period = 1800
healthcheck_port = "traffic-port"
elb_zone = var.elb_zone
min_size = length(var.subnets)
ports = [3306]
nlb_cname = "sandbox.proxysql"
aws_instance_type = "c5.xlarge"
pinfo_env = "sandbox"
}
WhyTF module
● Cookiecutter
○ Repeatable infrastructure
○ Good for juniors
● Splits complexity:
○ module maintainer vs module user
● Versioning
● Testable
What module creates
resource "aws_launch_configuration" "proxysql_zero" {...}
resource "aws_autoscaling_group" "proxysql_zero" {...}
resource "aws_placement_group" "proxysql_placement" {...}
resource "aws_autoscaling_lifecycle_hook" "terminating" {...}
resource "aws_autoscaling_policy" "cpu_load" {...}
auto_scaling.tf dns.tf
load_balance.tf outputs.tf
What module creates
resource "aws_lb" "proxysql" {...}
resource "aws_lb_listener" "proxysql" {...}
resource "aws_lb_target_group" "proxysql" {...}
auto_scaling.tf dns.tf
load_balance.tf outputs.tf
What module creates
resource "aws_route53_record" "elb" {
name = "${var.backend_type}.proxysql"
type = "CNAME"
ttl = local.dns_ttl
zone_id = data.aws_route53_zone.nlb_zone.id
records = [
aws_lb.proxysql.dns_name
]
}
auto_scaling.tf dns.tf
load_balance.tf outputs.tf
What module creates
output "nlb_dns_name" {
value = aws_lb.proxysql.dns_name
}
output "nlb_cname" {
value = aws_route53_record.elb.name
}
auto_scaling.tf dns.tf
load_balance.tf outputs.tf
Healthchecks
Two decisions to make:
1. Shall I forward traffic to X?
2. Shall I terminate X?
?
Load
Balancer
?
resource "aws_autoscaling_group" "proxysql_zero" {
…
health_check_type = “EC2|ELB”
…
}
ELB type Healthchecks
● Traffic port vs health check port
● TCP connection success?
○ Yes
■ Forward traffic
○ No
■ Do not forward traffic
■ Terminate instance
:8080
:3306
EC2 type Healthchecks
● Traffic port == health check port
● TCP connection success?
○ Yes
■ Forward traffic
○ No
■ Do not forward traffic
● ProxySQL healthcheck agent
:8080
:3306
try:
self.check_health(cursor)
self.check_at_least_one_live(cursor)
self.check_whg_count(cursor)
self.check_instance_state(local_instance)
self.mark_healthy(local_instance)
except:
self.mark_unhealthy(local_instance)
Zero downtime migration
● Needed when change:
○ AMI, subnet, security group, IAM role
○ ami-12345678 -> ami-87654321
● Blue/green deployment
● Must be tested for a proof
Load
Balancer
Zero downtime migration: Step 1
resource "aws_launch_configuration" "proxysql_zero" {
…
}
resource "aws_autoscaling_group" "proxysql_zero" {
name =
"${local.asg_prefix}-${aws_launch_configuration.proxysql_zero.name}"
target_group_arns = aws_lb_target_group.proxysql[*].arn
lifecycle {
create_before_destroy = true
}
}
Zero downtime migration: Step 2
resource "aws_launch_configuration" "proxysql_zero" {
…
}
resource "aws_autoscaling_group" "proxysql_zero" {
name =
"${local.asg_prefix}-${aws_launch_configuration.proxysql_zero.name}"
target_group_arns = aws_lb_target_group.proxysql[*].arn
lifecycle {
create_before_destroy = true
}
}
Zero downtime migration: Step 3
resource "aws_launch_configuration" "proxysql_zero" {
…
}
resource "aws_autoscaling_group" "proxysql_zero" {
name =
"${local.asg_prefix}-${aws_launch_configuration.proxysql_zero.name}"
target_group_arns = aws_lb_target_group.proxysql[*].arn
lifecycle {
create_before_destroy = true
}
}
Zero downtime migrations: How to test
Must be tested (tests/zero_downtime/test_zero_downtime.py)
Plan:
● ProxySQL acts as an HTTP server
● Create pool A
● Start a probe in a loop
● Create pool B
● Watch for probe errors
Testing a module: terraform-ci
def test_zero_downtime(ec2_client):
# Pool A
with open(osp.join(terraform_dir, "configuration.tfvars"), "w") as fp:
fp.write(configuration_template.format(payload=”old payload”))
with terraform_apply(terraform_dir) as tf_output:
proxysql_nlb = tf_output["proxysql_nlb"]["value"]
# Probe
que = Queue()
child = Process(target=ping, args=(url, que))
# Pool B
with open(osp.join(terraform_dir, "configuration.tfvars"), "w") as fp:
fp.write(configuration_template.format(payload=”new payload”))
with terraform_apply(terraform_dir):
child.terminate()
result = que.get()
assert result["error"] == 0
terraform-ci · PyPI
test_data/main.tf
module "proxysql" {
source = "../"
...
iam_instance_profile = aws_iam_instance_profile.ProxySQL_development.arn
ports = [22, local.traffic_port]
user_data_base64 = data.template_cloudinit_config.cloud_config["proxysql"].rendered
aws_instance_type = "t3.micro"
wait_for_capacity_timeout = "10m"
}
ProxySQL user-data
userdata_proxysql = format(
"#cloud-confign%s",
yamlencode(
{
write_files : [
{
content : var.index_content,
path : "/root/index.html"
},
]
package_update : true
packages : [...],
runcmd : [
"hostname proxysql",
"pip3 install webdev",
"cd /root; webdev -p ${local.traffic_port} &",
"/usr/local/bin/drain.sh &"
]
}
)
)
Test results
Destroy complete! Resources: 24 destroyed.
2022-05-16 13:53:39,416: INFO: __init__.execute():416: Executing: terraform destroy
-var-file=configuration.tfvars -input=false -auto-approve
Changes to Outputs:
- subnet_ids = [
- "subnet-5c19e837",
- "subnet-53d7411f",
- "subnet-43d5fa39",
] -> null
- traffic_port = 13 -> null
- vpc_id = "vpc-2ef53c45" -> null
- zone_id = "Z07524281VZN9F9H2TZCX" -> null
You can apply this plan to save these new output values to the Terraform
state, without changing any real infrastructure.
Destroy complete! Resources: 0 destroyed.
PASSED
======================== 1 passed in 1098.00s (0:18:18) ========================
Puppet
(rare changes)
Bootstrapping instance
AWS Starts EC2 instance
AMI starts cloud-init
cloud-init starts puppet
User-data
[root@proxysql-0a01b51c:~]# ec2metadata --user-data
#cloud-config
pinfo_team: proxysql
pinfo_env: sandbox
pinfo_role: sandboxdb
backend_type: sandboxdb
spiffe_id: spiffe://pin220.com/ec2/proxysql/sandboxdb
Puppet: what to run?!
[root@proxysql-0a01b51c:~]# puppet lookup 
--facts /etc/facter/facts.d/pinfo-$HOSTNAME.yaml 
--merge deep 
--hiera_config /mnt/puppet/hiera.yaml 
--render-as json classes
["pinterest::profile::proxysql"]
Example: Puppet
---
proxysql_manager::package_version: "latest"
pinterest::profile::proxysql::mtls::enabled: true
pinterest::profile::proxysql::package_version: "2.3.2"
class pinterest::profile::proxysql (...) {
service { 'proxysql':
ensure => running,
provider => 'debian',
require => Exec['generate_proxysql_cnf']
}
service { "proxysql-manager-agent":
ensure => $enabled ? { true => running, default => stopped },
subscribe => Package['proxysql-manager'],
require => [
Package['proxysql-manager'],
File["/etc/proxysql-manager-agent.conf"],
File["/etc/systemd/system/proxysql-manager-agent.service"],
]
}
}
Bootstrap ProxySQL configuration
[root@proxysql:~]# proxysql-manager generate-config --save-to=/dev/stdout
datadir="/var/lib/proxysql"
errorlog="/var/lib/proxysql/proxysql.log"
admin_variables={
admin_credentials="superadmin:qwerty"
mysql_ifaces="127.0.0.1:6032"
}2022-05-16 19:05:25,546: INFO: MainProcess(30966) generate_config.generate_config():35: Successfully saved
ProxySQL config in /dev/stdout
ProxySQL Manager logs
class pinterest::profile::proxysql_efs (
$efs_dir,
$efs_target,
$efs_mount_options = 'nfsvers=4.1',
) {
file { $efs_dir:
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
mount { $efs_dir:
ensure => mounted,
atboot => true,
device => $efs_target,
fstype => 'nfs4',
options => $efs_mount_options,
require => [
Package['nfs-common'],
File[$efs_dir],
]
}
}
ProxySQL Manager logs
[root@proxysql-sharddb-prod-0a019037:~]# df -h /var/log/proxysql
Filesystem Size Used Avail Use% Mounted on
proxysql-efs-prod.pinadmin.com:/ 8.0E 102G 8.0E 1% /var/log/proxysql
# ll /var/log/proxysql-manager.log
lrwxrwxrwx 1 root root 58 May 13 02:01 /var/log/proxysql-manager.log ->
/var/log/proxysql/i-0ec0c1de5b2190f4a/proxysql-manager.log
Python:
frequent changes
Arch & Workflow (GitOps)
VCS
Jenkins
SoT
ProxySQL
Node
agent
ProxySQL
Node
agent
ProxySQL
Node
agent
git
test
deploy
test
watch
Data model
CREATE TABLE global_variables (
variable_name VARCHAR NOT NULL PRIMARY KEY,
variable_value VARCHAR NOT NULL
)
Table is a Class
[root@proxysql-sharddb-prod-0a019037:~]# proxysql-manager admin login -e "show tables"
+----------------------------------------------------+
| tables |
+----------------------------------------------------+
| global_variables |
| mysql_aws_aurora_hostgroups |
| mysql_collations |
| mysql_firewall_whitelist_rules |
| mysql_firewall_whitelist_sqli_fingerprints |
| mysql_firewall_whitelist_users |
| mysql_galera_hostgroups |
| mysql_group_replication_hostgroups |
| mysql_query_rules |
| mysql_query_rules_fast_routing |
| mysql_replication_hostgroups |
| mysql_servers |
| mysql_users |
| scheduler |
+----------------------------------------------------+
mysql_servers
PSList (table == list of records)
Source of Truth(s)
● SourceOfTruth(ABC):
● SOTLocalProxy(SourceOfTruth):
● SOTRemoteMySQL(SourceOfTruth):
ProxySQL Manager
# proxysql-manager
Usage: proxysql-manager [OPTIONS] COMMAND [ARGS]...
ProxySQL manager helps to manage local ProxySQL instance
Options:
--debug Print debug messages
-q, --quiet Print only errors
--logfile TEXT Log messages to this file [default: /var/log/proxysql-
manager.log]
--version Show the version and exit.
--help Show this message and exit.
Commands:
admin ProxySQL admin credentials
deregister-server Deregister MySQL server from a ProxySQL Source of...
deregister-unknown Deregister non-ZK MySQL servers.
expert ProxySQL manager advanced commands.
generate-config Generate ProxySQL config and save it on disk.
is-server-registered The tool will inspect the latest ProxySQL config...
register-server Register MySQL server in a ProxySQL Source of Truth.
show-backends Show all backend types and their NLB DNS name.
show-instance Show ProxySQL instance for given backend_type
show-instances Same as ``proxysql-manager show-instance`` command.
start-agent Update latest configuration to local ProxySQL.
start-healthcheck Health check for upstream NLB.
sync-sot Synchronize ProxySQL config to remote Source of...
ProxySQL Manager: Agent
def _watch_table(self, klass, interval):
"""
Start agent daemon.
:param klass: Table class to watch
:param int interval: Time in seconds between SoT
checks.
"""
while True:
with global_lock():
if klass == PSMysqlUsers:
self._sync_mysql_users_with_knox()
else:
self.update_one_table(klass)
sleep(interval)
ProxySQL Manager: Agent (cont)
def update_one_table(self, tblclass):
try:
pslist = self._source_of_truth.read(tblclass, self._backend_type)
if pslist.version and pslist.version > self.versions[tblclass]:
# pslist is empty or pslist has newer version
LOG.info(
"It is a new version %d for table %s",
pslist.version,
tblclass.TABLE,
)
self._local_proxysql.write(pslist)
self.versions[tblclass] = pslist.version
self.update_versions_file(tblclass=tblclass, version=pslist.version)
self._handle_fallback(pslist)
ProxySQL Manager: Healthcheck
def watcher(self, credentials):
while True:
try:
with connection.cursor() as cursor:
self.check_health(cursor)
self._check_at_least_one_live(cursor)
self._check_whg_count(cursor)
self._check_instance_state(local_instance)
self._mark_healthy(local_instance)
except (
ProxySQLNotHealthy,
MySQLError,
ConnectionRefusedError,
) as err:
self._unhealthy_count += 1
LOG.error(err)
if self._unhealthy_count > self._healthy_threshold:
self._mark_unhealthy(local_instance)
else:
LOG.warning("Health check failed %d times", self._unhealthy_count)
sleep(self._probe_interval)
Source of Truth configuration
mysql_query_rules.json
[
{
"proxy_port": 3306,
"active": 1,
"rule_id": 1,
"destination_hostgroup": 1
}
]
mysql_users.json
[
{
"username": "knox://<knox key>",
"default_hostgroup": 3,
"attributes": {
"spiffe_id": "spiffe://pin220.com/foo"
},
"comment": {
"fallback_group": 4
}
},
]
● global_variables.json
● mysql_replication_hostgroups.json
Thank you!
https://twitter.com/OleksandrKuzm

Contenu connexe

Tendances

Replication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDReplication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDMydbops
 
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera ) Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera ) Mydbops
 
ProxySQL in the Cloud
ProxySQL in the CloudProxySQL in the Cloud
ProxySQL in the CloudRené Cannaò
 
ProxySQL High Avalability and Configuration Management Overview
ProxySQL High Avalability and Configuration Management OverviewProxySQL High Avalability and Configuration Management Overview
ProxySQL High Avalability and Configuration Management OverviewRené Cannaò
 
[2018] MySQL 이중화 진화기
[2018] MySQL 이중화 진화기[2018] MySQL 이중화 진화기
[2018] MySQL 이중화 진화기NHN FORWARD
 
Running MariaDB in multiple data centers
Running MariaDB in multiple data centersRunning MariaDB in multiple data centers
Running MariaDB in multiple data centersMariaDB plc
 
Maxscale switchover, failover, and auto rejoin
Maxscale switchover, failover, and auto rejoinMaxscale switchover, failover, and auto rejoin
Maxscale switchover, failover, and auto rejoinWagner Bianchi
 
MySQL GTID Concepts, Implementation and troubleshooting
MySQL GTID Concepts, Implementation and troubleshooting MySQL GTID Concepts, Implementation and troubleshooting
MySQL GTID Concepts, Implementation and troubleshooting Mydbops
 
Patroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easyPatroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easyAlexander Kukushkin
 
MariaDB MaxScale
MariaDB MaxScaleMariaDB MaxScale
MariaDB MaxScaleMariaDB plc
 
Maxscale_메뉴얼
Maxscale_메뉴얼Maxscale_메뉴얼
Maxscale_메뉴얼NeoClova
 
MySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptxMySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptxNeoClova
 
Percona XtraDB Cluster ( Ensure high Availability )
Percona XtraDB Cluster ( Ensure high Availability )Percona XtraDB Cluster ( Ensure high Availability )
Percona XtraDB Cluster ( Ensure high Availability )Mydbops
 
MaxScale이해와활용-2023.11
MaxScale이해와활용-2023.11MaxScale이해와활용-2023.11
MaxScale이해와활용-2023.11NeoClova
 
MySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software TestMySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software TestI Goo Lee
 
The Zen of High Performance Messaging with NATS
The Zen of High Performance Messaging with NATS The Zen of High Performance Messaging with NATS
The Zen of High Performance Messaging with NATS NATS
 
The Full MySQL and MariaDB Parallel Replication Tutorial
The Full MySQL and MariaDB Parallel Replication TutorialThe Full MySQL and MariaDB Parallel Replication Tutorial
The Full MySQL and MariaDB Parallel Replication TutorialJean-François Gagné
 
MySQL Database Architectures - InnoDB ReplicaSet & Cluster
MySQL Database Architectures - InnoDB ReplicaSet & ClusterMySQL Database Architectures - InnoDB ReplicaSet & Cluster
MySQL Database Architectures - InnoDB ReplicaSet & ClusterKenny Gryp
 
NATS vs HTTP for Interservice Communication
NATS vs HTTP for Interservice CommunicationNATS vs HTTP for Interservice Communication
NATS vs HTTP for Interservice CommunicationNATS
 
MariaDB 10.11 key features overview for DBAs
MariaDB 10.11 key features overview for DBAsMariaDB 10.11 key features overview for DBAs
MariaDB 10.11 key features overview for DBAsFederico Razzoli
 

Tendances (20)

Replication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDReplication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTID
 
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera ) Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
Wars of MySQL Cluster ( InnoDB Cluster VS Galera )
 
ProxySQL in the Cloud
ProxySQL in the CloudProxySQL in the Cloud
ProxySQL in the Cloud
 
ProxySQL High Avalability and Configuration Management Overview
ProxySQL High Avalability and Configuration Management OverviewProxySQL High Avalability and Configuration Management Overview
ProxySQL High Avalability and Configuration Management Overview
 
[2018] MySQL 이중화 진화기
[2018] MySQL 이중화 진화기[2018] MySQL 이중화 진화기
[2018] MySQL 이중화 진화기
 
Running MariaDB in multiple data centers
Running MariaDB in multiple data centersRunning MariaDB in multiple data centers
Running MariaDB in multiple data centers
 
Maxscale switchover, failover, and auto rejoin
Maxscale switchover, failover, and auto rejoinMaxscale switchover, failover, and auto rejoin
Maxscale switchover, failover, and auto rejoin
 
MySQL GTID Concepts, Implementation and troubleshooting
MySQL GTID Concepts, Implementation and troubleshooting MySQL GTID Concepts, Implementation and troubleshooting
MySQL GTID Concepts, Implementation and troubleshooting
 
Patroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easyPatroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easy
 
MariaDB MaxScale
MariaDB MaxScaleMariaDB MaxScale
MariaDB MaxScale
 
Maxscale_메뉴얼
Maxscale_메뉴얼Maxscale_메뉴얼
Maxscale_메뉴얼
 
MySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptxMySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptx
 
Percona XtraDB Cluster ( Ensure high Availability )
Percona XtraDB Cluster ( Ensure high Availability )Percona XtraDB Cluster ( Ensure high Availability )
Percona XtraDB Cluster ( Ensure high Availability )
 
MaxScale이해와활용-2023.11
MaxScale이해와활용-2023.11MaxScale이해와활용-2023.11
MaxScale이해와활용-2023.11
 
MySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software TestMySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software Test
 
The Zen of High Performance Messaging with NATS
The Zen of High Performance Messaging with NATS The Zen of High Performance Messaging with NATS
The Zen of High Performance Messaging with NATS
 
The Full MySQL and MariaDB Parallel Replication Tutorial
The Full MySQL and MariaDB Parallel Replication TutorialThe Full MySQL and MariaDB Parallel Replication Tutorial
The Full MySQL and MariaDB Parallel Replication Tutorial
 
MySQL Database Architectures - InnoDB ReplicaSet & Cluster
MySQL Database Architectures - InnoDB ReplicaSet & ClusterMySQL Database Architectures - InnoDB ReplicaSet & Cluster
MySQL Database Architectures - InnoDB ReplicaSet & Cluster
 
NATS vs HTTP for Interservice Communication
NATS vs HTTP for Interservice CommunicationNATS vs HTTP for Interservice Communication
NATS vs HTTP for Interservice Communication
 
MariaDB 10.11 key features overview for DBAs
MariaDB 10.11 key features overview for DBAsMariaDB 10.11 key features overview for DBAs
MariaDB 10.11 key features overview for DBAs
 

Similaire à ProxySQL at Scale on AWS.pdf

如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰KAI CHU CHUNG
 
Easy Cloud Native Transformation using HashiCorp Nomad
Easy Cloud Native Transformation using HashiCorp NomadEasy Cloud Native Transformation using HashiCorp Nomad
Easy Cloud Native Transformation using HashiCorp NomadBram Vogelaar
 
Container Orchestration from Theory to Practice
Container Orchestration from Theory to PracticeContainer Orchestration from Theory to Practice
Container Orchestration from Theory to PracticeDocker, Inc.
 
Tweaking performance on high-load projects
Tweaking performance on high-load projectsTweaking performance on high-load projects
Tweaking performance on high-load projectsDmitriy Dumanskiy
 
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski buildacloud
 
Kubernetes Navigation Stories – DevOpsStage 2019, Kyiv
Kubernetes Navigation Stories – DevOpsStage 2019, KyivKubernetes Navigation Stories – DevOpsStage 2019, Kyiv
Kubernetes Navigation Stories – DevOpsStage 2019, KyivAleksey Asiutin
 
Skydive, real-time network analyzer, container integration
Skydive, real-time network analyzer, container integrationSkydive, real-time network analyzer, container integration
Skydive, real-time network analyzer, container integrationSylvain Afchain
 
Terraform for azure: the good, the bad and the ugly -
Terraform for azure: the good, the bad and the ugly -Terraform for azure: the good, the bad and the ugly -
Terraform for azure: the good, the bad and the ugly -Giulio Vian
 
Velocity 2018 preetha appan final
Velocity 2018   preetha appan finalVelocity 2018   preetha appan final
Velocity 2018 preetha appan finalpreethaappan
 
Managing Terraform Module Versioning and Dependencies
Managing Terraform Module Versioning and Dependencies Managing Terraform Module Versioning and Dependencies
Managing Terraform Module Versioning and Dependencies Nebulaworks
 
Workshop Consul .- Service Discovery & Failure Detection
Workshop Consul .- Service Discovery & Failure DetectionWorkshop Consul .- Service Discovery & Failure Detection
Workshop Consul .- Service Discovery & Failure DetectionVincent Composieux
 
6 Months Sailing with Docker in Production
6 Months Sailing with Docker in Production 6 Months Sailing with Docker in Production
6 Months Sailing with Docker in Production Hung Lin
 
Container orchestration from theory to practice
Container orchestration from theory to practiceContainer orchestration from theory to practice
Container orchestration from theory to practiceDocker, Inc.
 
Terraform at Scale - All Day DevOps 2017
Terraform at Scale - All Day DevOps 2017Terraform at Scale - All Day DevOps 2017
Terraform at Scale - All Day DevOps 2017Jonathon Brouse
 
Clug 2012 March web server optimisation
Clug 2012 March   web server optimisationClug 2012 March   web server optimisation
Clug 2012 March web server optimisationgrooverdan
 
HKG15-204: OpenStack: 3rd party testing and performance benchmarking
HKG15-204: OpenStack: 3rd party testing and performance benchmarkingHKG15-204: OpenStack: 3rd party testing and performance benchmarking
HKG15-204: OpenStack: 3rd party testing and performance benchmarkingLinaro
 
Kubernetes Networking - Giragadurai Vallirajan
Kubernetes Networking - Giragadurai VallirajanKubernetes Networking - Giragadurai Vallirajan
Kubernetes Networking - Giragadurai VallirajanNeependra Khare
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akkanartamonov
 

Similaire à ProxySQL at Scale on AWS.pdf (20)

如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
 
Easy Cloud Native Transformation using HashiCorp Nomad
Easy Cloud Native Transformation using HashiCorp NomadEasy Cloud Native Transformation using HashiCorp Nomad
Easy Cloud Native Transformation using HashiCorp Nomad
 
Container Orchestration from Theory to Practice
Container Orchestration from Theory to PracticeContainer Orchestration from Theory to Practice
Container Orchestration from Theory to Practice
 
Tweaking performance on high-load projects
Tweaking performance on high-load projectsTweaking performance on high-load projects
Tweaking performance on high-load projects
 
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski
Troubleshooting Strategies for CloudStack Installations by Kirk Kosinski
 
Kubernetes Navigation Stories – DevOpsStage 2019, Kyiv
Kubernetes Navigation Stories – DevOpsStage 2019, KyivKubernetes Navigation Stories – DevOpsStage 2019, Kyiv
Kubernetes Navigation Stories – DevOpsStage 2019, Kyiv
 
Osol Pgsql
Osol PgsqlOsol Pgsql
Osol Pgsql
 
Skydive, real-time network analyzer, container integration
Skydive, real-time network analyzer, container integrationSkydive, real-time network analyzer, container integration
Skydive, real-time network analyzer, container integration
 
Terraform for azure: the good, the bad and the ugly -
Terraform for azure: the good, the bad and the ugly -Terraform for azure: the good, the bad and the ugly -
Terraform for azure: the good, the bad and the ugly -
 
Velocity 2018 preetha appan final
Velocity 2018   preetha appan finalVelocity 2018   preetha appan final
Velocity 2018 preetha appan final
 
Zero down time ECS cluster upgrades
Zero down time ECS cluster upgradesZero down time ECS cluster upgrades
Zero down time ECS cluster upgrades
 
Managing Terraform Module Versioning and Dependencies
Managing Terraform Module Versioning and Dependencies Managing Terraform Module Versioning and Dependencies
Managing Terraform Module Versioning and Dependencies
 
Workshop Consul .- Service Discovery & Failure Detection
Workshop Consul .- Service Discovery & Failure DetectionWorkshop Consul .- Service Discovery & Failure Detection
Workshop Consul .- Service Discovery & Failure Detection
 
6 Months Sailing with Docker in Production
6 Months Sailing with Docker in Production 6 Months Sailing with Docker in Production
6 Months Sailing with Docker in Production
 
Container orchestration from theory to practice
Container orchestration from theory to practiceContainer orchestration from theory to practice
Container orchestration from theory to practice
 
Terraform at Scale - All Day DevOps 2017
Terraform at Scale - All Day DevOps 2017Terraform at Scale - All Day DevOps 2017
Terraform at Scale - All Day DevOps 2017
 
Clug 2012 March web server optimisation
Clug 2012 March   web server optimisationClug 2012 March   web server optimisation
Clug 2012 March web server optimisation
 
HKG15-204: OpenStack: 3rd party testing and performance benchmarking
HKG15-204: OpenStack: 3rd party testing and performance benchmarkingHKG15-204: OpenStack: 3rd party testing and performance benchmarking
HKG15-204: OpenStack: 3rd party testing and performance benchmarking
 
Kubernetes Networking - Giragadurai Vallirajan
Kubernetes Networking - Giragadurai VallirajanKubernetes Networking - Giragadurai Vallirajan
Kubernetes Networking - Giragadurai Vallirajan
 
Above the clouds: introducing Akka
Above the clouds: introducing AkkaAbove the clouds: introducing Akka
Above the clouds: introducing Akka
 

Plus de Aleksandr Kuzminsky

Plus de Aleksandr Kuzminsky (8)

Omnibus as a Solution for Dependency Hell
Omnibus as a Solution for Dependency HellOmnibus as a Solution for Dependency Hell
Omnibus as a Solution for Dependency Hell
 
Efficient Indexes in MySQL
Efficient Indexes in MySQLEfficient Indexes in MySQL
Efficient Indexes in MySQL
 
Efficient Use of indexes in MySQL
Efficient Use of indexes in MySQLEfficient Use of indexes in MySQL
Efficient Use of indexes in MySQL
 
Netstore overview
Netstore overviewNetstore overview
Netstore overview
 
Undrop for InnoDB
Undrop for InnoDBUndrop for InnoDB
Undrop for InnoDB
 
Undrop for InnoDB
Undrop for InnoDBUndrop for InnoDB
Undrop for InnoDB
 
Data recovery talk on PLUK
Data recovery talk on PLUKData recovery talk on PLUK
Data recovery talk on PLUK
 
Recovery of lost or corrupted inno db tables(mysql uc 2010)
Recovery of lost or corrupted inno db tables(mysql uc 2010)Recovery of lost or corrupted inno db tables(mysql uc 2010)
Recovery of lost or corrupted inno db tables(mysql uc 2010)
 

Dernier

TRENDS Enabling and inhibiting dimensions.pptx
TRENDS Enabling and inhibiting dimensions.pptxTRENDS Enabling and inhibiting dimensions.pptx
TRENDS Enabling and inhibiting dimensions.pptxAndrieCagasanAkio
 
Company Snapshot Theme for Business by Slidesgo.pptx
Company Snapshot Theme for Business by Slidesgo.pptxCompany Snapshot Theme for Business by Slidesgo.pptx
Company Snapshot Theme for Business by Slidesgo.pptxMario
 
ETHICAL HACKING dddddddddddddddfnandni.pptx
ETHICAL HACKING dddddddddddddddfnandni.pptxETHICAL HACKING dddddddddddddddfnandni.pptx
ETHICAL HACKING dddddddddddddddfnandni.pptxNIMMANAGANTI RAMAKRISHNA
 
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书rnrncn29
 
Cybersecurity Threats and Cybersecurity Best Practices
Cybersecurity Threats and Cybersecurity Best PracticesCybersecurity Threats and Cybersecurity Best Practices
Cybersecurity Threats and Cybersecurity Best PracticesLumiverse Solutions Pvt Ltd
 
SCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is prediSCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is predieusebiomeyer
 
IP addressing and IPv6, presented by Paul Wilson at IETF 119
IP addressing and IPv6, presented by Paul Wilson at IETF 119IP addressing and IPv6, presented by Paul Wilson at IETF 119
IP addressing and IPv6, presented by Paul Wilson at IETF 119APNIC
 
Unidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptxUnidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptxmibuzondetrabajo
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书rnrncn29
 

Dernier (9)

TRENDS Enabling and inhibiting dimensions.pptx
TRENDS Enabling and inhibiting dimensions.pptxTRENDS Enabling and inhibiting dimensions.pptx
TRENDS Enabling and inhibiting dimensions.pptx
 
Company Snapshot Theme for Business by Slidesgo.pptx
Company Snapshot Theme for Business by Slidesgo.pptxCompany Snapshot Theme for Business by Slidesgo.pptx
Company Snapshot Theme for Business by Slidesgo.pptx
 
ETHICAL HACKING dddddddddddddddfnandni.pptx
ETHICAL HACKING dddddddddddddddfnandni.pptxETHICAL HACKING dddddddddddddddfnandni.pptx
ETHICAL HACKING dddddddddddddddfnandni.pptx
 
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
 
Cybersecurity Threats and Cybersecurity Best Practices
Cybersecurity Threats and Cybersecurity Best PracticesCybersecurity Threats and Cybersecurity Best Practices
Cybersecurity Threats and Cybersecurity Best Practices
 
SCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is prediSCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is predi
 
IP addressing and IPv6, presented by Paul Wilson at IETF 119
IP addressing and IPv6, presented by Paul Wilson at IETF 119IP addressing and IPv6, presented by Paul Wilson at IETF 119
IP addressing and IPv6, presented by Paul Wilson at IETF 119
 
Unidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptxUnidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptx
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
 

ProxySQL at Scale on AWS.pdf

  • 1. ProxySQL at Scale on AWS Percona Live 2022
  • 2. Challenges ● Over 100 diverse backend types, 400+ EC2 instances ○ Different query routing ○ Different users and configurations ● Cloud environment ○ Short lived instances ○ Shorter lifetime ● Disposable infrastructure ○ Configuration drift ○ History of changes
  • 3. Three level provisioning ● AWS resources ○ Load balancer ○ Auto Scaling Group ○ CNAME ● Zero downtime migrations ● OS level ● Packages ● Configs ● Services ● Config Agent ○ ProxySQL final configuration ○ Updating configs ○ Restarts ● Healthchecks ○ Flexible logic
  • 4. Guiding principles ● Infrastructure as code ○ Git as UI ● Declarative is favored over imperative ● Terraform - one time change ● Puppet - rare changes ● Python - frequent changes
  • 7. Example: Terraform module "sandboxdb" { source = "git::ssh://git@p.com/terraform-aws-proxysql.git?ref=4.0.0" security_group_ids = [ data.aws_security_group.proxysql["vpc-db-automation"].id, data.aws_security_group.proxysql["proxysql_use1_healthcheck"].id, data.aws_security_group.proxysql["proxysql_data"].id, data.aws_security_group.proxysql["vpc-dev-data-layer"].id ] iam_instance_profile = data.aws_iam_instance_profile.proxysql.arn aws_ami = var.aws_ami_map["default"] subnets = var.subnets backend_type = "sandboxdb" enable_deletion_protection = false health_check_type = "EC2" health_check_grace_period = 1800 healthcheck_port = "traffic-port" elb_zone = var.elb_zone min_size = length(var.subnets) ports = [3306] nlb_cname = "sandbox.proxysql" aws_instance_type = "c5.xlarge" pinfo_env = "sandbox" }
  • 8. WhyTF module ● Cookiecutter ○ Repeatable infrastructure ○ Good for juniors ● Splits complexity: ○ module maintainer vs module user ● Versioning ● Testable
  • 9. What module creates resource "aws_launch_configuration" "proxysql_zero" {...} resource "aws_autoscaling_group" "proxysql_zero" {...} resource "aws_placement_group" "proxysql_placement" {...} resource "aws_autoscaling_lifecycle_hook" "terminating" {...} resource "aws_autoscaling_policy" "cpu_load" {...} auto_scaling.tf dns.tf load_balance.tf outputs.tf
  • 10. What module creates resource "aws_lb" "proxysql" {...} resource "aws_lb_listener" "proxysql" {...} resource "aws_lb_target_group" "proxysql" {...} auto_scaling.tf dns.tf load_balance.tf outputs.tf
  • 11. What module creates resource "aws_route53_record" "elb" { name = "${var.backend_type}.proxysql" type = "CNAME" ttl = local.dns_ttl zone_id = data.aws_route53_zone.nlb_zone.id records = [ aws_lb.proxysql.dns_name ] } auto_scaling.tf dns.tf load_balance.tf outputs.tf
  • 12. What module creates output "nlb_dns_name" { value = aws_lb.proxysql.dns_name } output "nlb_cname" { value = aws_route53_record.elb.name } auto_scaling.tf dns.tf load_balance.tf outputs.tf
  • 13. Healthchecks Two decisions to make: 1. Shall I forward traffic to X? 2. Shall I terminate X? ? Load Balancer ? resource "aws_autoscaling_group" "proxysql_zero" { … health_check_type = “EC2|ELB” … }
  • 14. ELB type Healthchecks ● Traffic port vs health check port ● TCP connection success? ○ Yes ■ Forward traffic ○ No ■ Do not forward traffic ■ Terminate instance :8080 :3306
  • 15. EC2 type Healthchecks ● Traffic port == health check port ● TCP connection success? ○ Yes ■ Forward traffic ○ No ■ Do not forward traffic ● ProxySQL healthcheck agent :8080 :3306 try: self.check_health(cursor) self.check_at_least_one_live(cursor) self.check_whg_count(cursor) self.check_instance_state(local_instance) self.mark_healthy(local_instance) except: self.mark_unhealthy(local_instance)
  • 16. Zero downtime migration ● Needed when change: ○ AMI, subnet, security group, IAM role ○ ami-12345678 -> ami-87654321 ● Blue/green deployment ● Must be tested for a proof Load Balancer
  • 17. Zero downtime migration: Step 1 resource "aws_launch_configuration" "proxysql_zero" { … } resource "aws_autoscaling_group" "proxysql_zero" { name = "${local.asg_prefix}-${aws_launch_configuration.proxysql_zero.name}" target_group_arns = aws_lb_target_group.proxysql[*].arn lifecycle { create_before_destroy = true } }
  • 18. Zero downtime migration: Step 2 resource "aws_launch_configuration" "proxysql_zero" { … } resource "aws_autoscaling_group" "proxysql_zero" { name = "${local.asg_prefix}-${aws_launch_configuration.proxysql_zero.name}" target_group_arns = aws_lb_target_group.proxysql[*].arn lifecycle { create_before_destroy = true } }
  • 19. Zero downtime migration: Step 3 resource "aws_launch_configuration" "proxysql_zero" { … } resource "aws_autoscaling_group" "proxysql_zero" { name = "${local.asg_prefix}-${aws_launch_configuration.proxysql_zero.name}" target_group_arns = aws_lb_target_group.proxysql[*].arn lifecycle { create_before_destroy = true } }
  • 20. Zero downtime migrations: How to test Must be tested (tests/zero_downtime/test_zero_downtime.py) Plan: ● ProxySQL acts as an HTTP server ● Create pool A ● Start a probe in a loop ● Create pool B ● Watch for probe errors
  • 21. Testing a module: terraform-ci def test_zero_downtime(ec2_client): # Pool A with open(osp.join(terraform_dir, "configuration.tfvars"), "w") as fp: fp.write(configuration_template.format(payload=”old payload”)) with terraform_apply(terraform_dir) as tf_output: proxysql_nlb = tf_output["proxysql_nlb"]["value"] # Probe que = Queue() child = Process(target=ping, args=(url, que)) # Pool B with open(osp.join(terraform_dir, "configuration.tfvars"), "w") as fp: fp.write(configuration_template.format(payload=”new payload”)) with terraform_apply(terraform_dir): child.terminate() result = que.get() assert result["error"] == 0 terraform-ci · PyPI
  • 22. test_data/main.tf module "proxysql" { source = "../" ... iam_instance_profile = aws_iam_instance_profile.ProxySQL_development.arn ports = [22, local.traffic_port] user_data_base64 = data.template_cloudinit_config.cloud_config["proxysql"].rendered aws_instance_type = "t3.micro" wait_for_capacity_timeout = "10m" }
  • 23. ProxySQL user-data userdata_proxysql = format( "#cloud-confign%s", yamlencode( { write_files : [ { content : var.index_content, path : "/root/index.html" }, ] package_update : true packages : [...], runcmd : [ "hostname proxysql", "pip3 install webdev", "cd /root; webdev -p ${local.traffic_port} &", "/usr/local/bin/drain.sh &" ] } ) )
  • 24. Test results Destroy complete! Resources: 24 destroyed. 2022-05-16 13:53:39,416: INFO: __init__.execute():416: Executing: terraform destroy -var-file=configuration.tfvars -input=false -auto-approve Changes to Outputs: - subnet_ids = [ - "subnet-5c19e837", - "subnet-53d7411f", - "subnet-43d5fa39", ] -> null - traffic_port = 13 -> null - vpc_id = "vpc-2ef53c45" -> null - zone_id = "Z07524281VZN9F9H2TZCX" -> null You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure. Destroy complete! Resources: 0 destroyed. PASSED ======================== 1 passed in 1098.00s (0:18:18) ========================
  • 26. Bootstrapping instance AWS Starts EC2 instance AMI starts cloud-init cloud-init starts puppet
  • 27. User-data [root@proxysql-0a01b51c:~]# ec2metadata --user-data #cloud-config pinfo_team: proxysql pinfo_env: sandbox pinfo_role: sandboxdb backend_type: sandboxdb spiffe_id: spiffe://pin220.com/ec2/proxysql/sandboxdb
  • 28. Puppet: what to run?! [root@proxysql-0a01b51c:~]# puppet lookup --facts /etc/facter/facts.d/pinfo-$HOSTNAME.yaml --merge deep --hiera_config /mnt/puppet/hiera.yaml --render-as json classes ["pinterest::profile::proxysql"]
  • 29. Example: Puppet --- proxysql_manager::package_version: "latest" pinterest::profile::proxysql::mtls::enabled: true pinterest::profile::proxysql::package_version: "2.3.2" class pinterest::profile::proxysql (...) { service { 'proxysql': ensure => running, provider => 'debian', require => Exec['generate_proxysql_cnf'] } service { "proxysql-manager-agent": ensure => $enabled ? { true => running, default => stopped }, subscribe => Package['proxysql-manager'], require => [ Package['proxysql-manager'], File["/etc/proxysql-manager-agent.conf"], File["/etc/systemd/system/proxysql-manager-agent.service"], ] } }
  • 30. Bootstrap ProxySQL configuration [root@proxysql:~]# proxysql-manager generate-config --save-to=/dev/stdout datadir="/var/lib/proxysql" errorlog="/var/lib/proxysql/proxysql.log" admin_variables={ admin_credentials="superadmin:qwerty" mysql_ifaces="127.0.0.1:6032" }2022-05-16 19:05:25,546: INFO: MainProcess(30966) generate_config.generate_config():35: Successfully saved ProxySQL config in /dev/stdout
  • 31. ProxySQL Manager logs class pinterest::profile::proxysql_efs ( $efs_dir, $efs_target, $efs_mount_options = 'nfsvers=4.1', ) { file { $efs_dir: ensure => directory, owner => 'root', group => 'root', mode => '0755', } mount { $efs_dir: ensure => mounted, atboot => true, device => $efs_target, fstype => 'nfs4', options => $efs_mount_options, require => [ Package['nfs-common'], File[$efs_dir], ] } }
  • 32. ProxySQL Manager logs [root@proxysql-sharddb-prod-0a019037:~]# df -h /var/log/proxysql Filesystem Size Used Avail Use% Mounted on proxysql-efs-prod.pinadmin.com:/ 8.0E 102G 8.0E 1% /var/log/proxysql # ll /var/log/proxysql-manager.log lrwxrwxrwx 1 root root 58 May 13 02:01 /var/log/proxysql-manager.log -> /var/log/proxysql/i-0ec0c1de5b2190f4a/proxysql-manager.log
  • 34. Arch & Workflow (GitOps) VCS Jenkins SoT ProxySQL Node agent ProxySQL Node agent ProxySQL Node agent git test deploy test watch
  • 35. Data model CREATE TABLE global_variables ( variable_name VARCHAR NOT NULL PRIMARY KEY, variable_value VARCHAR NOT NULL )
  • 36. Table is a Class [root@proxysql-sharddb-prod-0a019037:~]# proxysql-manager admin login -e "show tables" +----------------------------------------------------+ | tables | +----------------------------------------------------+ | global_variables | | mysql_aws_aurora_hostgroups | | mysql_collations | | mysql_firewall_whitelist_rules | | mysql_firewall_whitelist_sqli_fingerprints | | mysql_firewall_whitelist_users | | mysql_galera_hostgroups | | mysql_group_replication_hostgroups | | mysql_query_rules | | mysql_query_rules_fast_routing | | mysql_replication_hostgroups | | mysql_servers | | mysql_users | | scheduler | +----------------------------------------------------+
  • 38. PSList (table == list of records)
  • 39. Source of Truth(s) ● SourceOfTruth(ABC): ● SOTLocalProxy(SourceOfTruth): ● SOTRemoteMySQL(SourceOfTruth):
  • 40. ProxySQL Manager # proxysql-manager Usage: proxysql-manager [OPTIONS] COMMAND [ARGS]... ProxySQL manager helps to manage local ProxySQL instance Options: --debug Print debug messages -q, --quiet Print only errors --logfile TEXT Log messages to this file [default: /var/log/proxysql- manager.log] --version Show the version and exit. --help Show this message and exit. Commands: admin ProxySQL admin credentials deregister-server Deregister MySQL server from a ProxySQL Source of... deregister-unknown Deregister non-ZK MySQL servers. expert ProxySQL manager advanced commands. generate-config Generate ProxySQL config and save it on disk. is-server-registered The tool will inspect the latest ProxySQL config... register-server Register MySQL server in a ProxySQL Source of Truth. show-backends Show all backend types and their NLB DNS name. show-instance Show ProxySQL instance for given backend_type show-instances Same as ``proxysql-manager show-instance`` command. start-agent Update latest configuration to local ProxySQL. start-healthcheck Health check for upstream NLB. sync-sot Synchronize ProxySQL config to remote Source of...
  • 41. ProxySQL Manager: Agent def _watch_table(self, klass, interval): """ Start agent daemon. :param klass: Table class to watch :param int interval: Time in seconds between SoT checks. """ while True: with global_lock(): if klass == PSMysqlUsers: self._sync_mysql_users_with_knox() else: self.update_one_table(klass) sleep(interval)
  • 42. ProxySQL Manager: Agent (cont) def update_one_table(self, tblclass): try: pslist = self._source_of_truth.read(tblclass, self._backend_type) if pslist.version and pslist.version > self.versions[tblclass]: # pslist is empty or pslist has newer version LOG.info( "It is a new version %d for table %s", pslist.version, tblclass.TABLE, ) self._local_proxysql.write(pslist) self.versions[tblclass] = pslist.version self.update_versions_file(tblclass=tblclass, version=pslist.version) self._handle_fallback(pslist)
  • 43. ProxySQL Manager: Healthcheck def watcher(self, credentials): while True: try: with connection.cursor() as cursor: self.check_health(cursor) self._check_at_least_one_live(cursor) self._check_whg_count(cursor) self._check_instance_state(local_instance) self._mark_healthy(local_instance) except ( ProxySQLNotHealthy, MySQLError, ConnectionRefusedError, ) as err: self._unhealthy_count += 1 LOG.error(err) if self._unhealthy_count > self._healthy_threshold: self._mark_unhealthy(local_instance) else: LOG.warning("Health check failed %d times", self._unhealthy_count) sleep(self._probe_interval)
  • 44. Source of Truth configuration mysql_query_rules.json [ { "proxy_port": 3306, "active": 1, "rule_id": 1, "destination_hostgroup": 1 } ] mysql_users.json [ { "username": "knox://<knox key>", "default_hostgroup": 3, "attributes": { "spiffe_id": "spiffe://pin220.com/foo" }, "comment": { "fallback_group": 4 } }, ] ● global_variables.json ● mysql_replication_hostgroups.json