我们需要用spark来处理图片、视频,这种数据用HDFS来存储很不合适,在我看来主要有两个问题:

  • HDFS的block size一般为64MB或者128MB,但图片一般可能1MB左右,浪费空间
  • 图片文件的数量可能很大,对NameNode的内存会是个挑战

针对交通卡口的图片,国内有公司是使用HBase做的存储,用Spark来处理。HBase默认一个Cell的大小是64KB,需要根据实际情况调整为1MB或者2MB。但HBase实际是不支持二进制持文件存储的,需要先将文件Base64转过以后再存储。另HBase的Cell的空间固定(?),不能作为一个比较通用的存储方案。

从需求上来讲,实际上我们需要的是一个对象存储工具。开源有Ceph/swift,亚马逊有S3,阿里云有oss。当然Ceph不只是对象存储,还是块存储、文件系统,有关Ceph和swift的对比可以看swift开发者是怎么说的

S3

摘自AWS官网的介绍:

Amazon Simple Storage Service (Amazon S3) 是一种面向 Internet 的存储服务。您可以通过 Amazon S3 随时在 Web 上的任何位置存储和检索的任意大小的数据。您可以使用 AWS 管理控制台简单而直观的 web 界面来实现这些任务。

如果使用过七牛的同学对这种“存储服务”应该不陌生。在国内使用S3有两种途径:

  • 登录AWS开通S3服务,不符合需求,过
  • 使用S3 Compatible的软件自建,如Ceph,或cooka同学推荐的minio

由于我们的使用场景可能是公安内网这种连css文件都下载不了的神奇环境,AWS可以直接pass掉了,剩下的就是选择一个生产环境下稳定可靠的S3 Compatible,Ceph是我们的不二人选。(因为我司在北京有一个很专业的Ceph团队。)

我这里只是做TEST,所以没有搭建Ceph集群,只是一个Ceph的docker。另外也试用了下minio。

Ceph/Demo的安装

优酷上有个视频详细说明了Ceph/Demo的build方式。有几个注意点:

1、docker镜像

Ceph的docker镜像源码在github上说,只要一条命令就搞定了:

docker run -d --net=host -v /etc/ceph:/etc/ceph -e MON_IP=192.168.0.20 -e CEPH_PUBLIC_NETWORK=192.168.0.0/24 ceph/demo

默认是从Docker hub上去拖的,But在国内,这一条docker run实在太慢了。国内USTC有一个docker镜像源,但是我怎么也没配置成功(找不到tag),最后采用了一个很曲折的办法:


2016-7-27 update: 重新试了下,USTC的源没问题,应该是之前我的用法有问题:

1、参照USTC的Docker镜像使用帮助,ubuntu配置/etc/default/docker,加入一行:

DOCKER_OPTS="--registry-mirror=https://docker.mirrors.ustc.edu.cn"

2、重启docker服务:service docker restart

3、docker pull,注意要加上USTC前缀,速度非常快:

# docker pull docker.mirrors.ustc.edu.cn/ceph/demo
Using default tag: latest
latest: Pulling from ceph/demo
56eb14001ceb: Pull complete
7ff49c327d83: Pull complete
6e532f87f96d: Pull complete
3ce63537e70c: Pull complete
4ad3cd54f9eb: Pull complete
efde6a540021: Pull complete
8a3945ffcab9: Pull complete
658f667cf359: Pull complete
fc3fb5adae44: Pull complete
Digest: sha256:63e89c93f6c370ff443b0833cd465b4df834e2de983826f55e486bf1b1f86074
Status: Downloaded newer image for docker.mirrors.ustc.edu.cn/ceph/demo:latest

国内的DaoCloud提供了免费的胶囊主机,可以使用120分钟。可能DaoCloud优化过胶囊主机的网络,也可能使用的是自己的mirror,总之docker pull速度还是不错的。胶囊主机可以从本地ssh上去,我在这个主机中先从Docker hub中下载ceph/demo,然后save成tar包,scp到我自己的机器上,最后再load。

# 胶囊主机上
docker pull ceph/demo
docker save ceph/demo > ceph.tar
# 本地机器上
scp user@xxxx/ceph.tar ceph.tar
docker load --input ceph.tar

然后执行上面的docker run命令,注意MON_IP是本机服务器的地址,ceph docker就跑起来了,docker exec -i -t xxxxx /bin/bash就进到docker容器中了。容器直接使用宿主机的网络。

类似阿里云OSS,S3的访问也是使用AK(额不好意思,应该是阿里云抄的AWS),后面不管是s3cmd、hadoop还是spark访问S3,都需要AK。

2、pip

视频中为了安装boto(官方Python SDK),还安装了pip,后面会用pip来安装boto等工具。但如你所愿,pip在国内也是渣渣,好在这个镜像比较多,使用也很简单:

pip install boto -i https://pypi.tuna.tsinghua.edu.cn/simple

如果要固话配置,可以修改~/.pip/pip.conf

[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple

注意,视频作者的目的是为了使用python来处理ceph s3,但对我们来说,其实只要一个s3cmd这种客户端就可以了,安装boto/ipython这些步骤可以跳过。

3、s3cmd

s3cmd可以用pip来安装,也可以用apt-get。配置比较简单,只要在当前用户的家目录下配置.s3cfg即可。原始内容从这里拷贝,需要修改如下几项:

access_key = xxxxx
secret_key = yyyyy
host_base = zelda2:80
host_bucket = zelda2:80

s3cmd使用比较简单,不知道命令直接敲s3cmd看帮助信息即可。下面贴几条常用的:

s3cmd mb s3://xxx
s3cmd put diamonds.csv  s3://xxx
s3cmd get s3://xxx/diamonds.csv
s3cmd del s3://xxx/diamonds.csv

S3的文件以bucket来组织,我们可以简单认为bucket就是文件系统的目录,上面的xxx为S3中的一个bucket。注意bucketname只能是字母、”-“、”.”。不能用下划线。

至此,Ceph提供的S3 Service就OK了,后面几篇文章会讲使用Hadoop和Spark访问S3服务。

minio

minio使用起来非常简单,只需要3步:

  1. 官网下载对应版本的minio可执行文件
  2. 创建准备用来存储minio的目录,最好空间大一点
  3. 启动minio服务:sudo ./minio server --address ":9000" /home/ieevee/s3/share/

minio可以使用s3cmd做客户端进行管理,但如果你觉得s3cmd不那么友好,minio也提供了一个WEB服务器,端口号跟s3服务端口号一致,chrome浏览器登录的时候,填写AK即可。

minio

minio使用Go实现,跟其他Go实现的软件一样,小巧玲珑。不过minio只能用来做简单的本地S3测试,一些企业级的特性比较欠缺:HA、横向扩展、用户隔离等(甚至没找到它的日志在哪里)。


传送门:

Spark支持S3作为DataSource(一):S3及其开源实现

Spark支持S3作为DataSource(二):Hadoop集成S3 Service

Spark支持S3作为DataSource(三):Spark集成S3 Service

Spark支持S3作为DataSource(四):使用Spark处理存储在S3上的图片文件