如何在Ubuntu14.04上创建分片RethinkDB集群
介绍
RethinkDB 是一个 NoSQL 数据库。 它有一个易于使用的 API 用于与数据库交互。 RethinkDB 还使设置数据库集群变得简单; 也就是说,服务于相同数据库和表的服务器组。 集群是一种无需停机即可轻松扩展数据库的方法。
本教程将介绍如何设置集群、导入数据和保护它。 如果您是 RethinkDB 的新手,请先查看 本教程 中的基础知识,然后再深入了解更复杂的集群配置过程。
先决条件
本教程需要至少 2 个运行 Ubuntu 14.04 LTS 的 Droplet,名为重新思考1 & 重新思考2 (这些名称将在本教程中使用)。 在设置 RethinkDB 之前,您应该 在每个 Droplet 上设置一个非 root sudo 用户 - 这样做是一个很好的安全实践。
本教程还引用了Python客户端驱动,在本教程中有说明。
设置节点
RethinkDB 中的集群没有特殊节点; 它是一个纯粹的点对点网络。 在我们可以配置集群之前,我们需要安装 RethinkDB。 在每台服务器上,从您的主目录中,将 RethinkDB 密钥和存储库添加到 apt-get:
source /etc/lsb-release && echo "deb http://download.rethinkdb.com/apt $DISTRIB_CODENAME main" | sudo tee /etc/apt/sources.list.d/rethinkdb.list wget -qO- http://download.rethinkdb.com/apt/pubkey.gpg | sudo apt-key add -
然后更新 apt-get 并安装 RethinkDB:
sudo apt-get update sudo apt-get install rethinkdb
接下来,我们需要将 RethinkDB 设置为在启动时运行。 RethinkDB 附带了一个在启动时运行的脚本,但需要启用该脚本:
sudo cp /etc/rethinkdb/default.conf.sample /etc/rethinkdb/instances.d/cluster_instance.conf
启动脚本也用作配置文件。 让我们打开这个文件:
sudo nano /etc/rethinkdb/instances.d/cluster_instance.conf
机器的名称(Web 管理控制台和日志文件中的名称)在此文件中设置。 让我们通过找到该行(在最底部)使其与机器的主机名相同:
# machine-name=server1
并将其更改为:
machine-name=rethink1
(注意:如果在第一次启动 RethinkDB 之前没有设置名称,它会自动设置一个 DOTA 主题的名称。)
设置 RethinkDB,以便通过查找以下行从所有网络接口访问它:
# bind=127.0.0.1
并将其更改为:
bind=all
保存配置并关闭 nano(按 Ctrl-X
,然后按 Y
,然后按 Enter
)。 我们现在可以使用新的配置文件启动 RethinkDB:
sudo service rethinkdb start
你应该看到这个输出:
rethinkdb: cluster_instance: Starting instance. (logging to `/var/lib/rethinkdb/cluster_instance/data/log_file')
RethinkDB 现已启动并运行。
保护 RethinkDB
我们打开了 bind=all
选项,使 RethinkDB 可以从服务器外部访问。 这是不安全的。 因此,我们需要阻止 RethinkDB 访问 Internet。 但我们需要允许授权计算机访问其服务。
对于集群端口,我们将使用防火墙来封闭我们的集群。 对于 Web 管理控制台和驱动程序端口,我们将使用 SSH 隧道从服务器外部访问它们。 SSH 隧道通过 SSH 将客户端计算机上的请求重定向到远程计算机,使客户端能够访问仅在远程服务器的 localhost 名称空间上可用的所有服务。
在所有 RethinkDB 服务器上重复这些步骤。
首先,阻止所有外部连接:
# The Web Management Console sudo iptables -A INPUT -i eth0 -p tcp --dport 8080 -j DROP sudo iptables -I INPUT -i eth0 -s 127.0.0.1 -p tcp --dport 8080 -j ACCEPT # The Driver Port sudo iptables -A INPUT -i eth0 -p tcp --dport 28015 -j DROP sudo iptables -I INPUT -i eth0 -s 127.0.0.1 -p tcp --dport 28015 -j ACCEPT # The Cluster Port sudo iptables -A INPUT -i eth0 -p tcp --dport 29015 -j DROP sudo iptables -I INPUT -i eth0 -s 127.0.0.1 -p tcp --dport 29015 -j ACCEPT
有关配置 IPTables 的更多信息,请查看 本教程 。
让我们安装“iptables-persistent”来保存我们的规则:
sudo apt-get update sudo apt-get install iptables-persistent
你会看到这样的菜单:
选择Yes
选项(按Enter
)保存防火墙规则。 您还将看到有关 IPv6 规则的类似菜单,您也可以保存它。
设置管理用户
要访问 RethinkDB 的 Web 管理控制台和驱动程序界面,我们需要设置 SSH 隧道。 让我们在 rethink1 上为 ssh 隧道创建一个新用户:
sudo adduser ssh-to-me
然后为我们的新用户设置授权密钥文件:
sudo mkdir /home/ssh-to-me/.ssh sudo touch /home/ssh-to-me/.ssh/authorized_keys
如果您使用 SSH 连接到云服务器,请在 本地计算机 上打开一个终端。 如果您不是,您可能想 了解更多关于 SSH 密钥 的信息。 获取您的公钥并将其复制到剪贴板:
cat ~/.ssh/id_rsa.pub
然后通过打开服务器 上的 authorized_keys 文件 将该密钥添加到新帐户:
sudo nano /home/ssh-to-me/.ssh/authorized_keys
将您的密钥粘贴到文件中。 然后保存并关闭 nano(Ctrl-X
,然后 Y
,然后 Enter
)。
您需要对其他集群节点重复所有这些步骤。
导入或创建数据库
您可能希望将预先存在的数据库导入集群。 仅当您在另一台服务器或此服务器上具有预先存在的数据库时才需要这样做; 否则,RethinkDB 会自动创建一个空数据库。
如果需要导入外部数据库:
如果您要导入的数据库未存储在 rethink1
上,则需要将其复制过去。 首先,找到你当前 RethinkDB 数据库的路径。 如果您使用 rethinkdb
命令启动旧数据库,这将是自动创建的 rethinkdb_data
目录。 然后,在 rethink1 上使用 scp
复制它:
sudo scp -rpC From Server User@From Server IP:/RethinkDB Data Folder/* /var/lib/rethinkdb/cluster_instance/data
例如:
sudo scp -rpC root@111.222.111.222:/home/user/rethinkdb_data/* /var/lib/rethinkdb/cluster_instance/data
然后重启 RethinkDB:
sudo service rethinkdb restart
如果你在 rethink1 上有一个现有的数据库:
如果您在 rethink1 上有一个现有的 RethinkDB 数据库,则过程不同。 首先打开rethink1上的配置文件:
sudo nano /etc/rethinkdb/instances.d/cluster_instance.conf
然后,找到要导入的 RethinkDB 数据库的路径。 如果您使用 rethinkdb
命令启动旧数据库,这将是自动创建的 rethinkdb_data
目录。 通过添加以下行将该路径插入到配置文件中:
directory=/home/user/rethink/rethinkdb_data/
关闭文件以保存更改(使用 Ctrl-X
,然后是 Y
,然后是 Enter
)。 现在重新启动 RethinkDB:
sudo service rethinkdb restart
需要注意的是,导入预先存在的数据库将意味着 rethink1 将继承数据库旧机器的名称。 稍后在管理数据库分片时,您将需要知道这一点。
创建集群
为了创建集群,您需要允许所有集群机器通过彼此的防火墙。 在您的 rethink1 机器上,添加一条 IPTables 规则以允许其他节点通过防火墙。 在此示例中,您应该将 rethink2 IP
替换为该服务器的 IP 地址:
sudo iptables -I INPUT -i eth0 -s rethink2 IP -p tcp --dport 29015 -j ACCEPT
对要添加的任何其他节点重复该命令。
然后保存防火墙规则:
sudo sh -c "iptables-save > /etc/iptables/rules.v4"
然后对其他节点重复这些步骤。 对于两台服务器的设置,您现在应该连接到 rethink2 并取消阻止 rethink1 的 IP。
现在您需要连接所有节点以创建集群。 使用SSH连接rethink2,打开配置文件:
sudo nano /etc/rethinkdb/instances.d/cluster_instance.conf
join
选项指定要加入的集群的地址。 在配置文件中找到 join
行:
# join=example.com:29015
并将其替换为:
join=rethink1 IP
保存并关闭配置文件(使用 Ctrl-X
,然后是 Y
,然后是 Enter
)。 然后重启 RethinkDB:
sudo service rethinkdb restart
第一个节点 rethink1 不需要 join
更新。 在所有其他节点上重复配置文件编辑,除了 rethink1。
您现在拥有一个功能齐全的 RethinkDB 集群!
连接到 Web 管理控制台
Web 管理控制台是一个易于使用的在线界面,可以访问 RethinkDB 的基本管理功能。 当您需要查看集群状态、运行单个 RethinkDB 命令和更改基本表设置时,此控制台非常有用。
集群中的每个 RethinkDB 实例都服务于一个管理控制台,但这只能从服务器的 localhost 名称空间获得,因为我们使用防火墙规则将其与世界其他地方隔离开来。 我们可以使用 SSH 隧道将我们对 localhost:8080
的请求重定向到 rethink1,这会将请求发送到其名称空间内的 localhost:8080
。 这将允许您访问 Web 管理控制台。 您可以在 本地计算机 上使用 SSH 执行此操作:
ssh -L 8080:localhost:8080 ssh-to-me@rethink1 IP
如果您在浏览器中转到 localhost:8080,您现在将看到您的 RethinkDB Web 管理控制台。
如果您收到 bind: Address already in use
错误,则您已在计算机上使用端口 8080。 您可以将 Web 管理控制台转发到其他端口,该端口在您的计算机上可用。 例如,您可以将其转发到端口 8081 并转到 localhost:8081:
ssh -L 8081:localhost:8080 ssh-to-me@rethink1 IP
如果您发现关于拥有两个测试数据库的冲突,您可以重命名其中一个。
使用 Python 驱动程序连接到集群
在此设置中,所有 RethinkDB 服务器(Web 管理控制台、驱动程序端口和集群端口)都与外界隔绝。 我们可以使用 SSH 隧道连接到驱动程序端口,就像使用 Web 管理控制台一样。 驱动程序端口是 RethinkDB API 驱动程序(用于构建应用程序的驱动程序)连接到集群的方式。
首先,选择一个要连接的节点。 如果您有多个客户端(例如,Web 应用程序服务器)连接到集群,您需要在集群中平衡它们。 编写一个客户端列表,然后为每个客户端分配一个服务器是个好主意。 尝试对客户端进行分组,以便需要类似表的客户端连接到相同的云服务器或服务器组,这样就不会因为大量客户端而导致服务器过载。
在这个例子中,我们将使用 rethink2 作为我们的连接服务器。 但是,在数据库和 Web 应用程序服务器分开的较大系统中,您可能希望从实际进行数据库调用的 Web 应用程序服务器中执行此操作。
然后,在 连接服务器 上,生成 SSH 密钥:
ssh-keygen -t rsa
并将其复制到剪贴板:
cat ~/.ssh/id_rsa.pub
然后通过打开 authorized_keys
文件并将密钥粘贴到新行上来授权 集群节点 (在本例中为 rethink1)上的新密钥:
sudo nano /home/ssh-to-me/.ssh/authorized_keys
关闭 nano 并保存文件(Ctrl-X
,然后 Y
,然后 Enter
)。
接下来,使用 SSH 隧道从 连接服务器 访问驱动程序端口:
ssh -L 28015:localhost:28015 ssh-to-me@Cluster Node IP -f -N
现在可以从 localhost:28015 访问驱动程序。 如果您收到 bind: Address already in use
错误,您可以更改端口。 例如,使用端口 28016:
ssh -L 28016:localhost:28015 ssh-to-me@Cluster Node IP -f -N
在连接服务器上安装Python驱动。 这里有命令的快速浏览,您可以在 本教程 中更详细地了解它们。
安装 Python 虚拟环境:
sudo apt-get install python-virtualenv
制作 ~/rethink
目录:
cd ~ mkdir rethink
进入目录并创建新的虚拟环境结构:
cd rethink virtualenv venv
激活环境(每次启动Python界面前必须激活环境,否则会报缺少模块的错误):
source venv/bin/activate
安装 RethinkDB 模块:
pip install rethinkdb
现在从 连接服务器 启动 Python:
python
连接到数据库,确保将 28015
替换为您使用的端口,如有必要:
import rethinkdb as r r.connect("localhost", 28015).repl()
创建表 test
:
r.db("test").table_create("test").run()
将数据插入表 test
:
r.db("test").table("test").insert({"hello":"world"}).run() r.db("test").table("test").insert({"hello":"world number 2"}).run()
并打印出数据:
list(r.db("test").table("test").run())
您应该会看到类似于以下内容的输出:
[{u'hello': u'world number 2', u'id': u'0203ba8b-390d-4483-901d-83988e6befa1'}, {u'hello': u'world', u'id': u'7d17cd96-0b03-4033-bf1a-75a59d405e63'}]
设置分片
在 RethinkDB 中,您可以将表配置为跨多个云服务器分片(拆分)。 分片是一种简单的方法,可以让比单个机器的 RAM 更大的数据集运行良好,因为有更多的 RAM 可用于缓存。 由于分片还会将数据集拆分到多台机器上,因此您可以拥有更大、性能较低的表,因为该表有更多可用磁盘空间。 这可以通过 Web 管理控制台完成。
为此,请转到 Web 管理控制台中的 Tables 选项卡。
单击 test 表(我们在上一节中创建的)以输入其设置。 向下滚动到分片设置卡。
单击编辑按钮。 在那里,您可以输入要拆分表的服务器数量。 在此示例中输入 2。 点击 Rebalance 按钮保存设置。
您可能会注意到,您可以拥有的分片数量是有上限的。 这等于数据库中的文档数。 如果您尝试为新表设置分片,您将需要等待更多数据或添加虚拟数据以允许自己添加更多分片。
高级分片
在内部,RethinkDB 具有基于文档 ID 的基于范围的分片。 这意味着如果我们有一个 ID 为 A、B、C 和 D 的数据集,RethinkDB 可能会将其拆分为 2 个分片:A、B(-infinity 到 C)和 C、D(C 到 +infinity)。 如果您要插入 ID 为 A1 的文档,那将在第一个分片的范围内(-infinity 到 C),因此它将进入该分片。 我们可以设置分片的边界,这可以优化您的数据库配置。
在我们这样做之前,我们需要添加一个数据集来玩。 在 Web 管理控制台的 Data Explorer 选项卡中,我们可以通过运行以下命令来创建表(键入后单击 Run):
r.db('test').tableCreate('testShards')
然后插入我们的测试数据:
r.db("test").table("testShards").insert([ {id:"A"}, {id:"B"}, {id:"C"}, {id:"D"}, {id:"E"}])
现在我们可以详细配置分片。 为此,我们需要进入 admin shell。 admin shell 是一种更高级的控制集群的方法,允许您微调您的设置。 在 rethink1 机器上,打开 admin shell:
rethinkdb admin
然后我们可以查看我们表的一些信息:
ls test.testShards
预期输出:
table 'testShards' b91fda27-a9f1-4aeb-bf6c-a7a4211fb674 ... 1 replica for 1 shard shard machine uuid name primary -inf-+inf 91d89c12-01c7-487f-b5c7-b2460d2da22e rethink1 yes
在 RethinkDB 中,有很多方法可以命名表。 您可以使用 database.name
(test.testShards
)、名称 (testShards
) 或表 uuid (e780f2d2-1baf-4667-b725-b228c7869aab
)。 这些都可以互换使用。
让我们分割这个碎片。 我们将制作 2 个分片:-infinity 到 C 和 C 到 +infinity:
split shard test.testShards C
该命令的通用形式是:
split shard TABLE SPLIT-POINT
再次运行 ls testShards
显示分片已被拆分。 您可能希望将新分片从一台机器移动到另一台机器。 对于这个例子,我们可以将分片 -inf-C
(-infinty 到 C)固定(移动)到机器 rethink2:
pin shard test.testShards -inf-C --master rethink2
该命令的通用形式是:
pin shard TABLE SHARD-RANGE --master MACHINE-NAME
如果您再次 ls testShards
,您应该会看到分片已移动到不同的服务器。
如果我们知道公共边界,我们也可以合并 2 个分片。 让我们合并我们刚刚制作的分片(-infinity 到 C 和 C 到 +infinity):
merge shard test.testShards C
该命令的通用形式是:
merge shard TABLE COMMON-BOUNDARY
要退出 shell,请键入 exit
安全移除机器
当一个文档被拆分到多台机器上时,一台机器将始终保存其主索引。 如果具有特定文档的主索引的云服务器脱机,则该文档将丢失。 所以,在你移除一台机器之前,你应该把它上面的所有主分片从它上面迁移出去。
在此示例中,我们将尝试将数据迁移出节点 rethink2,以将 rethink1 作为唯一节点。
在 rethink1 上输入 RethinkDB admin shell:
rethinkdb admin
首先,让我们列出 rethink2 负责的分片(文档组):
ls rethink2
您的输出应如下所示:
machine 'rethink2' bc2113fc-efbb-4afc-a2ed-cbccb0c55897 in datacenter 00000000-0000-0000-0000-000000000000 hosting 1 replicas from 1 tables table name shard primary b91fda27-a9f1-4aeb-bf6c-a7a4211fb674 testShards -inf-+inf yes
这表明 rethink2 负责 id 为“bdfceefb-5ebe-4ca6-b946-869178c51f93”的表的主分片。 接下来,我们将把这个分片移动到 rethink1。 这称为固定:
pin shard test.testShards -inf-+inf --master rethink1
该命令的通用形式是:
pin shard TABLE SHARD-RANGE --master MACHINE-NAME
如果你现在运行 ls rethink1
你会看到分片已经被移动到那台机器上。 将每个分片从 rethink2 移动到 rethink1 后,您应该退出管理 shell:
exit
现在可以安全地在不需要的服务器上停止 RethinkDB。 重要提示:在您要 删除 的机器上运行它。 在这个例子中,我们将在 rethink2 上运行它:
sudo service rethinkdb stop
下次访问 Web 管理控制台时,RethinkDB 会显示一个鲜红色的警告。 单击解决问题。
如果显示的问题类似于上面的问题,并且没有列出主要职责,请单击 永久删除 。 这将从集群中删除机器。 如果它列出了任何主职责,请重新打开 RethinkDB (sudo service rethinkdb start
) 并确保将每个主分片迁移出该服务器。
注意:如果您尝试将机器重新添加到集群中,您将看到有关僵尸机器的消息。 您可以删除数据目录以纠正此问题:
sudo rm -r /var/lib/rethinkdb/cluster_instance/ sudo service rethinkdb restart