dot在您所在城市举行的活动体验速度的未来。

加入我们,参加 Redis 发布会

将 Redis 模块引入 ARM 领域 – 第 1 部分

在 Redis 中,我们引入 Redis 模块到 ARM 领域的动力是 RedisEdge。当然,Redis 在这个领域一直是本地化的,既有 glibc 也有 alpine/musl 变体。Redis 模块已经出现在多平台场景中,运行在各种 Linux 发行版上,主要为了开发体验而支持 macOS。然而,直到面向物联网设备的 RedisEdge 出现之前,它都更面向企业/数据中心。在这个系列文章中,我将描述我们对 ARM 平台支持和开发者用户体验的愿景,以及我们为实现这一目标所采取的步骤。

如果你继续关注,最终你会得到一个功能齐全的 ARM 构建实验室。

RedisEdge 内部

我们来看看 RedisEdge。RedisEdge 不是一个 Redis 模块,而是三个 Redis 模块的集合:RedisGears、RedisAI 和 RedisTimeSeries。它以 Docker 镜像的形式分发,该镜像基于 Redis Server 5.0。因此,人们可以简单地拉取该镜像,运行它,然后开始发出 Redis 命令;将模型加载到 RedisAI 中;并在 RedisGears 上执行 Python gears 脚本。虽然人们可以通过安装 Redis 服务器和复制 Redis 模块文件来轻松地从等式中删除 Docker,但我们将会看到 Docker 实际上提供了很大的附加值,值得保留。

RedisEdge 内部:模块结构

现在,我们来看看 RedisEdge 的每个组件,以弄清楚要将它们移植到 ARM 上需要做些什么。首先,RedisTimeSeries。它是一个简单的 C 库,使用 make 构建。甚至没有配置脚本。那里没有问题。接下来是 RedisGears。它是一个用纯 make 构建的 C 库,而且它还使用了一个从源代码构建的嵌入式 Python 3.7 解释器。这需要运行 automake 来生成一个特定于平台的 makefile。最后,RedisAI。它是一个用 CMake 构建的 C 库,它包含模块化的“引擎”,这些引擎允许抽象和封装 AI 库,如 TensorFlowPyTorchONNXRuntime,以它们的 C 库形式 — 大多数用户通常在 Python 中使用它们,而 PyTorch 和 ONNXRuntime 不正式支持 ARM。因此,构建要求似乎迅速恶化了。它从构建一个无害的 C 库变成了编译具有复杂构建系统的大量源代码库。

在以下部分中,我们将为每个组件选用合适的构建方法。

面向 ARM 构建

此时,我们先暂停一下,看看为 ARM 构建软件需要什么。显然的方法是使用基于 ARM 的设备,如 Raspberry Pi。一旦设置好,你将能够以最自然的方式构建和测试。

测试介质很重要:尽管你几乎可以用任何 ARM 设备构建软件,但想要对结果进行可靠的测试,尤其是非标准设备的测试,如果没有真实的 ARM 设备是不可能的。因此,尽管虚拟化的/模拟的/容器化的测试可能很有用,但你应当始终在指定的目标设备上测试你的软件。

4GB 内存(至少要 1Gbps NIC)的覆盆子 Pi 4 和快速 microSD 卡看上去很有前途。

关于 ARM 上的选择操作系统:产品很有限,经验法则就是选择 Raspbian(这是为 RPi 定制的 Debian 分布)、Ubuntu 或 Fedora 的最新版本,后两者提供易于安装的 ARM 系统。不用担心不成熟:事实已经证明,更新的系统工作得更好,而旧系统则跟不上。

安装操作系统会给我们带来第一个难题:如果我们安装 Raspbian,我们将会获得一个 32 位操作系统(即 arm32v7 平台)。如果我们选择 64 位 Ubuntu,我们将会得到一个 arm64v8 平台(稍后我们会详细讨论 ARM 平台)。如果我们打算支持两个平台(正如我们在 RedisEdge 中所做的那样),我们可以获得两张 SD 卡,将每套操作系统安装到它自己的卡中,然后在设备上轮流使用,或者获得两个 RPi 设备(这不是特别昂贵)。我推荐后者。

现在,为了操作系统选择的首要原则:我们的目标是拥有一个带有最新 Docker 版本的稳定系统。满足这些要求的任何操作系统都可以。没错:我们将使用 Docker 获取我们真正想要构建的操作系统,使用基础操作系统作为基础设施。这也有助于将我们的构建实验适当隔离。

如果你准备了一台 RPi 设备,你现在可以继续使其发挥功能。在下一篇文章中,我们将介绍不需要物理 ARM 机器就能构建的方法。

在 RPi 3 和 4 上安装 Ubuntu 19.04

有关如何在 RPi 上下载并安装适用于 ARM 的最新 Ubuntu Server 的非常优秀且详细的说明书,对于 Linux、Windows 和 macOS 可以 在这里 找到。然而,你应当按照以下说明安装 Ubuntu 19.04 而不是最新发布的版本

  • 获得一张 microSD 卡:64GB、Class 10,任何与三星 EVO 或 SanDisk Ultra 相当(即处于相同价位)的产品都可以。
  • 下载操作系统 镜像 (通常为 .img 或 .raw 格式,存档)并提取。虽然可以从 .iso 文件安装,但使用 .img 镜像更加简单易行,因此建议使用后者。
  • 使用 Balena Etcher 之类的工具将它写到 microSD 卡上(可用于所有平台,我个人使用 Win32 磁盘映像工具)。为了写入,你应当使用笔记本电脑中内置的 microSD 读卡器或通过 USB 接口获得外部读卡器。
  • 将 microSD 插入 RPi 并开机。
  • 用户名/密码:ubuntu/ubuntu

在 RPi 3 和 4 上安装 Raspbian Buster

  • 使用 Raspbian Lite 镜像重复上述步骤。
  • 用户名/密码:pi/raspberry

连接到工作站

对于“工作站”,我指的是一个 Linux 或 macOS 主机,它包含一个人的开发环境和 git 存储库。作为旁注,我强烈建议使用台式机(这是另一篇博文),尽管大多数人使用的是笔记本电脑。在任何情况下,我还建议在您的工作站上拥有某种虚拟化基础设施,例如 VMware Workstation/Fusion 或 VirtualBox。

因此,我们需要在 RPi 和工作站之间建立网络连接。如前所述,RPi 4 有一个 1Gbps NIC,这比具有 100Mbps NIC 的 RPi 3 有了很大改进。将 RPi 连接到网络非常简单:获取任何千兆以太网非托管交换机和两根以太网电缆,然后将 RPi 连接到交换机,并将交换机连接到您的网关以太网端口。您也可以将工作站连接到交换机。

在这一阶段,我们需要从工作站收集一些信息。

首先,我们需要确定拥有视图的工作站用户的 UID 和 GID

_id

我们将称它们为 MY-UID 和 MY-GID。

接下来,我们需要找出我们的时区是什么

timedatectl

我们将称其为 MY-TIMEZONE。

最后,我们需要您的工作站 IP

ip a

我们将称为 MY-WORKSTATION-IP。

RPi 配置

在初始设置期间,您需要将 RPi 连接到监视器和键盘。设置完成后,可以通过 SSH 从您的工作站进行控制。

另一个好习惯是避免将源代码克隆到 RPi 中,而是通过 NFS 在工作站和 RPi 之间共享源代码。

为方便起见,我假设我们是以 root 身份操作的(例如通过 sudo bash)。

那么,让我们开始配置

主机名
hostnamectl set-hostname MY-HOSTNAME
时区和 NTP
# recall MY-TIMEZONE from previous section
timedatectl set-timezone MY-TIMEZONE
# confirm settings
timedatectl
SSH 服务器
apt-get -qq update
apt install -qy openssh-server
systemctl start openssh-server
systemctl enable openssh-server
IP
ip a
# record ip address, connect via ssh from workstation
NFS 客户端
apt install -qy nfs-common
mkdir -p /mnt/views
ln -s /mnt/views /v

将以下内容添加到 etc/hosts

workstation MY-WORKSTATION-IP

此外,将以下行添加到 etc/fstab

workstation:/views /mnt/views nfs defaults 0 0
实用程序
apt install -qy tmux ca-certificates curl wget htop mc tmux

在工作站方面

关于 git 存储库,我将在讨论中使用以下术语和结构。这不是必需的,人们可以对问题进行不同的组织。术语“视图”是指一组 git 存储库克隆,这些克隆在特定上下文中使用。例如,如果我们在 ARM 编译的上下文中处理 RedisEdge 模块,我们将得到以下目录结构

/views/arm1/
	RedisEdge
	RedisTimeSeries
	RedisGears
	RedisAI

此处“arm1”是视图名称,其中包含的目录是相应 git clone 命令的结果。可能还有其他视图提供其他上下文。其想法是在所有主机和容器之间共享此结构,以避免移动代码和 git 密钥管理的麻烦。

为了更加方便,我添加了以下链接

mkdir /views
ln -s /views /v

因此,最后,我们着手设置 NFS。

现在以 root 身份进行

Ununtu/Debian

记下 MY-UID 和 MY-GID 值。

apt-get -qq update
apt-get install -qy nfs-kernel-server nfs-common
echo "/views *(rw,all_squash,anonuid=MY-UID,anongid=MY-GID)" >> /etc/exports
systemctl start nfs-kernel-server
systemctl enable nfs-kernel-server
Fedora/CentOS

记下 MY-UID 和 MY-GID 值。

yum install nfs-utils
echo "/views *(rw,all_squash,anonuid=MY-UID,anongid=MY-GID)" >> /etc/exports
systemctl start rpcbind nfs-server
systemctl enable rpcbind nfs-server

请注意,如果已启用工作站防火墙,它可能干扰 NFS。建议针对有线连接关闭防火墙。

返回 RPi

现在我们在工作站上设置好了 NFS,可以将 views 目录挂载到 RPi 中

mount -a
ls /v

最后,我们可以安装 Docker 和 Docker Compose。

在 Ubuntu 19.04 上安装 Docker
# install Docker
curl -fsSL https://get.docker.com | sh

# install Docker Compose
curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker- compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
在 Raspbian Buster 上安装 Docker
# install Docker
apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg2 \
    software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
add-apt-repository \
    "deb [arch=armhf] https://download.docker.com/linux/raspbian buster stable"
apt-get -qq update
apt-get install docker-ce docker-ce-cli containerd.io
# this will prevent "docker login" failure
rm -f /usr/bin/docker-credential-secretservice

# install Docker Compose
apt-get install -y pass gnupg2
apt-get install -y python libffi-dev python-openssl python-dev
curl -sSL https://bootstrap.pypa.io/get-pip.py | python
pip2 install docker-compose==1.24.1

在下一章中

在下一篇博文中,我将介绍我们努力追求的开发者体验,详细讨论 ARM 平台,介绍在不使用 ARM 硬件的情况下在 ARM 上进行构建的方法,并开始使用 RedisEdge 模块将理论付诸实践。

敬请期待!