我目前有一个标准的本地 LAMP 设置(2 个 Web 服务器、主/从 MySQL、负载均衡器)。这在本地运行良好,但我的全球用户却体验到速度缓慢。
我想在几个大洲设置一些 amazon ec2 节点。Web 部分不是问题,因为我可以将代码部署到所有地理 Web 服务器。但是,它们都需要数据库中的数据才能运行。
为所有地理位置设计一个数据库的最佳方法是什么?我考虑在每个位置都建立本地数据库,并将其复制到其他位置。从一个位置写入的内容不需要立即从另一个位置读取,但我绝对希望本地数据库的速度快一些。
我该如何做到这一点而不产生主键冲突等?
有没有更好的建筑设计?
感谢您的帮助。
答案1
证明网络延迟是问题所在
用户感受到速度缓慢的原因有很多。
虽然您可以尝试使用许多地理位置的本地 MySQL 实例解决此问题,但该设置会很复杂(并且成本也相当高)。
如果可能的话,您应该研究其他选项(例如数据库和应用程序逻辑)。
你的申请
你调查过你的应用逻辑吗?
您可能有太多数据库调用,导致整个应用程序速度变慢。应调查数据库索引、存储引擎、数据库字段类型和其他优化等问题。
您可以利用 AWS ElastiCache (http://aws.amazon.com/elasticache/) 或使用其他缓存技术在应用程序中短时间存储数据的本地副本。
如果不能完全替换 MySQL,您可能还考虑在应用程序的某些部分使用 NoSQL。
这些变化可能会对相对缓慢的影响巨大您的申请。
RDS——关系数据库
亚马逊有一项名为亚马逊关系数据库服务(Amazon RDS)的服务。
如果您必须使用关系数据库,您可能会发现 RDS 很有用。特别是以下功能可能会为您带来所需的性能提升。
预配置 IOPS- 您可以从标准存储转换为预配置 IOPS 存储,并获得一致的吞吐量和低 I/O 延迟。
只读副本可以结合使用以提高数据库可用性
虽然这些方法无法解决您的用户可能遇到的网络延迟问题。但在进一步研究之前,您应该确定问题出在网络延迟上(而不仅仅是 ISP 或客户端链接速度慢)。
其他数据库解决方案 (NoSQL)
AWS 为您提供了更多选择,http://aws.amazon.com/running_databases/
使用简单数据库或者DynamoDB可能更适合您的需要。
http://aws.amazon.com/dynamodb/
Amazon DynamoDB 是一种完全托管的服务,提供极快的性能、无缝的可扩展性和可靠性、低成本等。
http://aws.amazon.com/simpledb/
Amazon SimpleDB 是一种完全托管的服务,提供无模式数据库、可靠性等。
答案2
步骤 1:使用 SSL 设置 MySQL 主/从复制:启动两个 64 位 EC2 实例,并在 EC2 上安装 MySQL 数据库。整个设置都在 AWS Classic 云中完成,而不是 Amazon VPC。主 MySQL Amazon EC2 位于美国东部 (Master US-East-1a) 区域,一个用于 MySQL 从属的 Amazon EC2 位于亚太地区新加坡区域 (ap-southeast-1a)
步骤 2:在 MySQL Master & Slave Amazon EC2 上配置以下步骤以启用 SSL,编辑 my.cnf 文件
vim /etc/my.cnf
在 [mysqld] 部分添加一行带有 ssl 字样的内容:
ssl 重新启动 MySQL
mysql> show variables like '%ssl%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl | YES |
| have_ssl | YES |
| ssl_ca | |
| ssl_capath | |
| ssl_cert | |
| ssl_cipher | |
| ssl_key | |
+---------------+-------+
共 7 行 (0.00 秒)
响应显示 SSL 现已启用。
步骤 3:在 MySQL EC2 上创建 SSL 证书的步骤现在我们需要创建 SSL 连接所需的 CA、服务器和客户端证书。在目录 /etc/mysql/certs/ 中创建这些证书
步骤 3.1:在 MySQL Master EC2 上 - 创建 CA /服务器/客户端证书:mkdir -p /etc/mysql/certs cd /etc/mysql/certs openssl genrsa 2048 > ca-key.pem openssl req -new -x509 -nodes -days 1000 -key ca-key.pem > ca-cert.pem
创建服务器证书:openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem > server-req.pem openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem - set_seial 01 > server-cert.pem
创建客户端证书:
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem > client-req.pem
openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem
注意:创建证书时请使用“唯一通用名称”,否则 SSL 将不起作用。在 /etc/my.cnf 中的 [mysqld] 部分下添加以下 ssl-ca、ssl-cert 和 ssl-key 行
[mysqld]
ssl
ssl-ca=/etc/mysql/certs/ca-cert.pem
ssl-cert=/etc/mysql/certs/server-cert.pem
ssl-key=/etc/mysql/certs/server-key.pem
重新启动 MySQL 以加载 SSL 配置
步骤 3.2:在 MySQL Slave EC2 上配置证书 使用 SCP 将以下证书文件复制到 MySQL Slave EC2 的新目录 /etc/mysql/certs/ca-cert.pem,client-cert.pem,client-key.pem,server-cert.pem,server-key.pem 在 [mysqld] 下的 MySQL Slave /etc/my.cnf 中添加以下内容
[mysqld]
ssl
ssl-ca=/etc/mysql/certs/ca-cert.pem
ssl-cert=/etc/mysql/certs/client-cert.pem
ssl-key=/etc/mysql/certs/client-key.pem
重新启动 MySQL 以加载 SSL 配置。
步骤 4:配置复制设置步骤 4.1:在 MySQL Master Amazon EC2 上,在 /etc/my.cnf 中的 [mysqld] server_id = 1 log_bin = /var/log/mysql/mysql-bin.log #log_bin_index = /var/log/mysql/mysql-bin.log.index max_binlog_size = 100M expire_logs_days = 1
重启 MySQL
service mysqld restart
在主服务器的 MySQL EC2 shell 终端中执行以下操作:
注意:REQUIRE SSL 字符串是可选的;如果您省略它,slave_user 将被允许通过加密和非加密连接进行连接。如果您使用 REQUIRE SSL,则从服务器和主服务器之间只允许建立加密连接。
$ mysql -u root -p
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave_user1'@'%' IDENTIFIED BY 'mysql_mslave1' REQUIRE SSL;
mysql> FLUSH PRIVILEGES;
mysql> FLUSH TABLES WITH READ LOCK;
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 335 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
mysql> unlock tables;
mysql> quit
步骤 4.2:在 MySQL Slave EC2 实例上:编辑 my.cnf 文件 server-id = 2 log_bin = /var/log/mysql/mysql-bin.log #log_bin_index = /var/log/mysql/mysql-bin.log.index max_binlog_size = 100M expire_logs_days = 1
重启 MySQL 服务 mysqld restart
在Slave的MySQL EC2 shell终端中执行以下命令:
mysql -u root -p
mysql slave stop;
mysql> CHANGE MASTER TO MASTER_HOST='ec2-IP-49.compute-1.amazonaws.com', MASTER_USER='slave_user1', MASTER_PASSWORD='mysql_mslave1', MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=107,MASTER_SSL=1, MASTER_SSL_CA = '/etc/mysql/certs/ca-cert.pem', MASTER_SSL_CERT = '/etc/mysql/certs/client-cert.pem', MASTER_SSL_KEY = '/etc/mysql/certs/client-key.pem';
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS;
** there should be a message "Waiting for master to send event"
mysql>quit
步骤 5:测试 MySQL Master 与从属之间的 MySQL AWS 区域间复制:在 MySQL Master EC2 实例上 mysql -u root -pmysql> create database rep_test_US_APAC; mysql> use rep_test_US_APAC; mysql> CREATE TABLE t1(c1 int,c2 var(100));
注意:在亚太地区的 MySQL 从属 Amazon EC2 中,您可以找到已创建的数据库和表。下一步,将数据插入主 MySQL EC2,在几秒/几分钟的复制滞后检查中,您可以发现数据存在于从属服务器上。停止将记录插入主服务器并验证从属服务器是否是最新的,通过应用以下命令检查从属 EC2 上的复制滞后状态
$ mysql -u root -p -e 'show slave status\G' | grep -i seconds
Seconds_Behind_Master: 0
SHOW SLAVE STATUS \G
注意:Slave_IO_Running 和 Slave_SQL_Running 在输出中都具有值“Yes”非常重要(否则会出错,您应该再次检查配置步骤和 /var/log/syslog 以找出任何错误);由于您现在正在使用 SSL 连接,您还应该在字段 Master_SSL_Allowed、Master_SSL_CA_File、Master_SSL_Cert 和 Master_SSL_Key 中找到值。