MemSQL是一种内存数据库,可以提供比传统数据库更快的读写操作。即使它是一项新技术,它也会说MySQL协议,因此使用起来非常熟悉。
MemSQL已经采用了MySQL的最新功能和现代功能,例如JSON支持和数据插入功能。MemSQL over MySQL的最大优势之一是它能够跨多个节点拆分单个查询,称为大规模并行处理,从而实现更快的读取查询。
在本教程中,我们将在单个Ubuntu 14.04服务器上安装MemSQL,运行性能基准测试,并通过命令行MySQL客户端插入JSON数据。
要学习本教程,您需要:
-
在本节中,我们将为MemSQL安装准备工作环境。
最新版本的MemSQL列在其下载页面上。我们将下载并安装MemSQL Ops,这是一个管理下载和准备服务器以正确运行MemSQL的程序。在编写本文时,最新版本的MemSQL Ops是4.0.35。
首先,从他们的网站下载MemSQL的安装包文件。
wget http://download.memsql.com/memsql-ops-4.0.35/memsql-ops-4.0.35.tar.gz
接下来,提取包。
tar -xzf memsql-ops-4.0.35.tar.gz
提取包已创建一个名为memsql-ops-4.0.35
的文件夹。请注意,文件夹名称具有版本号,因此如果您下载的版本低于本教程指定的版本,您将拥有一个包含所下载版本的文件夹。
将目录更改为此文件夹。
cd memsql-ops-4.0.35
然后,运行安装脚本,它是我们刚刚提取的安装包的一部分。
sudo ./install.sh
您将看到脚本的一些输出。片刻之后,它会询问您是否只想在此主机上安装MemSQL。我们将在未来的教程中介绍如何在多台机器上安装MemSQL。所以,为了本教程的目的,让我们输入y来表示肯定。
. . .
Do you want to install MemSQL on this host only? [y/N] y
2015-09-04 14:30:38: Jd0af3b [INFO] Deploying MemSQL to 45.55.146.81:3306
2015-09-04 14:30:38: J4e047f [INFO] Deploying MemSQL to 45.55.146.81:3307
2015-09-04 14:30:48: J4e047f [INFO] Downloading MemSQL: 100.00%
2015-09-04 14:30:48: J4e047f [INFO] Installing MemSQL
2015-09-04 14:30:49: Jd0af3b [INFO] Downloading MemSQL: 100.00%
2015-09-04 14:30:49: Jd0af3b [INFO] Installing MemSQL
2015-09-04 14:31:01: J4e047f [INFO] Finishing MemSQL Install
2015-09-04 14:31:03: Jd0af3b [INFO] Finishing MemSQL Install
Waiting for MemSQL to start...
现在您已将一个MemSQL集群部署到您的Ubuntu服务器上!但是,从上面的日志中,您会注意到MemSQL已安装两次。
MemSQL可以作为两个不同的角色运行:聚合器节点和叶子节点。之前安装MemSQL的原因是因为它需要至少一个聚合器节点和至少一个叶节点才能运行集群。
该聚合器是你的界面MemSQL。对于外部世界,它看起来很像MySQL:它在同一个端口上侦听,你可以连接期望与MySQL和标准MySQL库交谈的工具。聚合器的工作是了解所有MemSQL叶节点,处理MySQL客户端,并将其查询转换为MemSQL。
甲叶节点实际存储的数据。当叶节点从聚合器节点接收到读取或写入数据的请求时,它执行该查询并将结果返回到聚合器节点。MemSQL允许您跨多个主机共享数据,每个叶节点都有一部分数据。(即使使用单个叶节点,您的数据也会在该叶节点内拆分。)
当您有多个叶节点时,聚合器负责将MySQL查询转换为该查询中应该涉及的所有叶节点。然后它接收来自所有叶节点的响应,并将结果聚合到一个返回MySQL客户端的查询中。这就是管理并行查询的方式。
我们的单主机设置在同一台机器上运行聚合器和叶节点,但您可以在许多其他机器上添加更多叶节点。
让我们看看MemSQL可以通过使用MemSQL Ops工具来快速运行,该工具是作为MemSQL安装脚本的一部分安装的。
在您的Web浏览器中,转到 http://your_server_ip:9000
MemSQL Ops工具为您提供了群集的概述。我们有2个MemSQL节点:主聚合器和叶节点。
让我们在单机MemSQL节点上进行速度测试。单击左侧菜单中的Speed Test,然后单击START TEST。以下是您可能会看到的结果示例:
我们将不介绍如何在本教程中跨多个服务器安装MemSQL,但为了进行比较,这里是一个带有三个8GB Ubuntu 14.04节点(一个聚合器节点和两个叶节点)的MemSQL集群的基准测试:
通过将叶节点的数量加倍,我们几乎可以使插入速率加倍。通过查看Rows Read部分,我们可以看到我们的三节点集群能够在相同的时间内同时读取比单节点集群多12M的行。
对于客户端,MemSQL看起来像MySQL; 他们都有着同样的协议。为了要开始与我们的MemSQL集群交谈,让我们先安装一个mysql-client。
首先,更新apt,以便我们在下一步安装最新的客户端。
sudo apt-get update
现在,安装一个MySQL客户端。这将给我们一个mysql
执行命令。
sudo apt-get install mysql-client-core-5.6
我们现在准备使用MySQL客户端连接到MemSQL。我们将以root用户身份连接到端口3306上的127.0.0.1
主机(这是我们的本地主机IP地址)。我们还将把提示消息自定义为memsql>
。
mysql -u root -h 127.0.0.1 -P 3306 --prompt="memsql> "
你会看到几行输出的后面写着memsql>
提示符。
我们列出数据库。
show databases;
你会看到这个输出。
+--------------------+
| Database |
+--------------------+
| information_schema |
| memsql |
| sharding |
+--------------------+
3 rows in set (0.01 sec)
创建一个名为tutorial的新数据库。
create database tutorial;
然后使用use
命令来切换至使用新数据库。
use tutorial;
接下来,我们将创建一个users
表,该表将有id
字段和email
字段。我们必须为这两个字段指定一个类型。让我们将id设为bigint并通过电子邮件发送长度为255的varchar。我们还将告诉数据库该id
字段是主键,并且该email
字段不能为空。
create table users (id bigint auto_increment primary key, email varchar(255) not null);
你可能会注意到最后一个命令的执行时间很短(15 - 20秒)。MemSQL创建这个新表的速度有一个主要原因:代码生成。
在引擎盖下,MemSQL使用代码生成来执行查询。这意味着每当遇到新类型的查询时,MemSQL都需要生成和编译代表查询的代码。然后将此代码发送到集群以供执行。这加快了处理实际数据的速度,但是准备成本很高。MemSQL尽其所能重用预先生成的查询,但是从未见过结构的新查询将会减速。
回到我们的用户表,看一下表定义。
describe users;
+-------+--------------+------+------+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+------+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| email | varchar(255) | NO | | NULL | |
+-------+--------------+------+------+---------+----------------+
2 rows in set (0.00 sec)
现在,让我们在users表中插入一些示例电子邮件。此语法与我们可能用于MySQL数据库的语法相同。
insert into users (email) values ('one@example.com'), ('two@example.com'), ('three@example.com');
Query OK, 3 rows affected (1.57 sec)
Records: 3 Duplicates: 0 Warnings: 0
现在查询users表。
select * from users;
您可以看到我们刚刚输入的数据:
+----+-------------------+
| id | email |
+----+-------------------+
| 2 | two@example.com |
| 1 | one@example.com |
| 3 | three@example.com |
+----+-------------------+
3 rows in set (0.07 sec)
MemSQL提供了JSON类型,因此在此步骤中,我们将创建一个事件表来使用传入事件。该表将包含一个id
字段(就像我们为用户所做的那样)和一个event
字段,该字段将是一个JSON类型。
create table events (id bigint auto_increment primary key, event json not null);
让我们插入几个事件。在JSON中,我们将引用一个email
字段,该字段又引用回到我们在步骤3中插入的用户的ID。
insert into events (event) values ('{"name": "sent email", "email": "one@example.com"}'), ('{"name": "received email", "email": "two@example.com"}');
现在我们可以看看刚刚插入的事件。
select * from events;
+----+-----------------------------------------------------+
| id | event |
+----+-----------------------------------------------------+
| 2 | {"email":"two@example.com","name":"received email"} |
| 1 | {"email":"one@example.com","name":"sent email"} |
+----+-----------------------------------------------------+
2 rows in set (3.46 sec)
接下来,我们可以查询其JSON name
属性是文本“已接收电子邮件”的所有事件。
select * from events where event::$name = 'received email';
+----+-----------------------------------------------------+
| id | event |
+----+-----------------------------------------------------+
| 2 | {"email":"two@example.com","name":"received email"} |
+----+-----------------------------------------------------+
1 row in set (5.84 sec)
尝试更改该查询以查找name
属性为“已发送电子邮件”文本的查询。
select * from events where event::$name = 'sent email';
+----+-------------------------------------------------+
| id | event |
+----+-------------------------------------------------+
| 1 | {"email":"one@example.com","name":"sent email"} |
+----+-------------------------------------------------+
1 row in set (0.00 sec)
这个最新的查询比前一个查询运行得快得多。这是因为我们只更改了查询中的参数,因此MemSQL能够跳过代码生成。
让我们为分布式SQL数据库做一些高级操作:让我们在非主键上连接两个表,其中一个连接值嵌套在一个JSON值中,但过滤不同的JSON值。
首先,我们将通过匹配事件名称为“已接收电子邮件”的电子邮件来请求加入事件表的用户表的所有字段。
select * from users left join events on users.email = events.event::$email where events.event::$name = 'received email';
+----+-----------------+------+-----------------------------------------------------+
| id | email | id | event |
+----+-----------------+------+-----------------------------------------------------+
| 2 | two@example.com | 2 | {"email":"two@example.com","name":"received email"} |
+----+-----------------+------+-----------------------------------------------------+
1 row in set (14.19 sec)
接下来,尝试相同的查询,但只过滤到“已发送电子邮件”事件。
select * from users left join events on users.email = events.event::$email where events.event::$name = 'sent email';
+----+-----------------+------+-------------------------------------------------+
| id | email | id | event |
+----+-----------------+------+-------------------------------------------------+
| 1 | one@example.com | 1 | {"email":"one@example.com","name":"sent email"} |
+----+-----------------+------+-------------------------------------------------+
1 row in set (0.01 sec)
像以前一样,第二个查询比第一个快得多。正如我们在基准测试中看到的那样,在执行数百万行时,代码生成的好处得到了回报。使用能够理解JSON的横向扩展SQL数据库以及如何在表之间任意连接的灵活性是一个强大的用户功能。
您已经安装了MemSQL,运行节点性能的基准测试,通过标准MySQL客户端与您的节点进行交互,并使用MySQL中没有的一些高级功能。这应该很好地了解内存中的SQL数据库可以为您做什么。
还有很多东西需要了解MemSQL如何实际分发您的数据,如何构建表以获得最佳性能,如何跨多个节点扩展MemSQL,如何复制数据以实现高可用性以及如何保护MemSQL。
更多Ubuntu教程请前往腾讯云+社区学习更多知识。
参考文献:《How to Install MemSQL on Ubuntu 14.04》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。