允许你以一种分布式和冗余的方式存储大量数据

作者: mgm娱乐网址  发布:2019-12-21

图片 1

MNIST 数据集已经是一个被"嚼烂"了的数据集, 很多教程都会对它"下手", 几乎成为一个 "典范". 不过有些人可能对它还不是很了解, 下面来介绍一下.

你准备好面试了吗?需要 Hadoop 的知识!!?不要慌!这里有一些可能会问到的问题以及你应该给出的答案。

如果你居住在印度,当不希望接受任何电话推销员的骚扰时,你可以在全国客户偏好登记册 中进行注册。政府维护了这个由用户注册的电话号码组成的数据库。现在,差不多有4亿个注册号码。所有注册的电话推销员必须及时更新数据,以保证他们在进行推销时会参考这个偏好设置进行工作。这些数据由一捆ZIP文件提供,每个ZIP文件包含一个10M的CSV文件。这篇文章将会讲述这2.4GB压缩后的数据如何基于一些简单的方式以一种可搜索的格式适配2GB的内存。数据下面是CSV文件一瞥关于存储在SQL引擎中的一些说明在内存为4GB的Linode机房的机器上, PostgreSQL数据表加载数据约需要10分钟:添加一个主键大约耗时1.5到2个小时:并使用32GB的硬盘空间:观察CSV数据分析了数据之后,我们可以看到:* 将近400M行数据* 电话号码全部是10位* 服务区域码是1-23之间的自然数* 偏好依靠`#`来界定,可能是`0`或者是{1,2,3,4,5,7}的组合* Ops类型用A表示启用,用D表示未启用* 电话号码类型是{1,2,3}中的一个这意味着一行数据可以用2个字节表示:第一个字节:1位存在标志位,5位服务区域码,2位电话号码类型。第二个字节:7位偏好,1位Ops类型。数据可以通过2*400MB来表示。存在标志位将会在下面的部分讨论。使之可搜索每个条目都会按照电话号码进行频繁的搜索,而目前我们并没有将数据与电话号码进行匹配。我们需要添加字节来存储电话号码。不幸的是,10个数字并不能放入32位中,使用5*400MB来存储数字并不是一个乐观的情况,而且根本没办法进行搜索。如果数据按顺序排列,那么索引为 (2*number) 和 (2*number+1)的内存位置便能给出所需的两个字节。空行可以用第一个字节中的存在标志表示。这意味着我们需要20GB的内存。我们能进一步压缩吗?该数组看起来很稀疏。我们的解决方案是:使用两种格式类型。更进一步我们还发现对于大多数移动手机号码的数组是密集的。所以,如果10个数字分成两部分——4位的前缀和6位的数字偏移量——这样一来,固定的4位前缀的所有可能值按顺序排列时,它们都可以被放入2MB的空间里了。。现在,搜索变得简单了,因为我们按照尾部进行偏移量计算,直接访问数组即可。这个稀疏的数列存储在5字节的序列中,3个字节表示尾部,2个字节表示数据。尾部按照升序排列,所以搜索变的简单了。对于持久化存储,具有相同前缀的数字存储在一个文件中,该文件的第一个字节是类型的指示框。这些共需1.8GB的空间,这些数据可以存储在内存中,通过webserver进行发布。加工处理使用快速Python脚本来转换CSV数据为我们需要的格式是十分耗时的。分析表明,大部分时间花费在迭代处理2M固定头部数据时。我们尝试使用xrange进行优化,但是5小时对于处理整个数据,尤其是PostgreSQL处理仅需要2小时,实在太多了。我们希望能有些快速响应,更符合心理预期。相同的程序选择Rust来实现,处理整个数据仅用20-30分钟。查找计时为了测量该解决方案的速度,我们随机生成了相同序列的电话号码。结果如下图所示。我们选取“9818”和“9000”开头的号码去分别计算查找密集框和稀疏框的时间。对于SQL解决方案,头部的密集程度并不影响。注意,在本次测量中,尽管我们为了公平起见,计时时包含了磁盘的读写,但是在我们的解决方案中,数据一旦被加载或放入内存中,不再需要磁盘访问,之后由于数据存储格式的优点,这个进程被加快。所有的测试都是在4GB的Linode机房机器上跑的,机器配置如下:引用SSD, 4GB RAM, 4 virtual CPU cores, CPU Model: Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHzAPI和开源在SparkTG,我们尊重客户的偏好设置。尽管我们的客户大部分都是与注册的客户交流,但我们还是保证他们最终不会拨出一个无关的电话。我们已经将该项目开源,并且提供API来查找号码NCPR状态,使得电话推销找不到方式拨打注册用户的电话。参考1. _Not_Disturb_Registry2. _telephone_numbering_in_India3. Github repository4. NCPR status lookup原文:How we store 400M phone number data with fast lookups译者:杰微刊-张帆

MNIST 数据集可在 http://yann.lecun.com/exdb/mnist/ 获取, 它包含了四个部分:

图片 2

  • Training set images: train-images-idx3-ubyte.gz (9.9 MB, 解压后 47 MB, 包含 60,000 个样本)
  • Training set labels: train-labels-idx1-ubyte.gz (29 KB, 解压后 60 KB, 包含 60,000 个标签)
  • Test set images: t10k-images-idx3-ubyte.gz (1.6 MB, 解压后 7.8 MB, 包含 10,000 个样本)
  • Test set labels: t10k-labels-idx1-ubyte.gz (5KB, 解压后 10 KB, 包含 10,000 个标签)

Q1.什么是 Hadoop?

MNIST 数据集来自美国国家标准与技术研究所, National Institute of Standards and Technology (NIST). 训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员. 测试集(test set) 也是同样比例的手写数字数据.

Hadoop 是一个开源软件框架,用于存储大量数据,并发处理/查询在具有多个商用硬件节点的集群上的那些数据。总之,Hadoop 包括以下内容:HDFS(Hadoop Distributed File System,Hadoop 分布式文件系统):HDFS 允许你以一种分布式和冗余的方式存储大量数据。例如,1 GB(即 1024 MB)文本文件可以拆分为 16 * 128MB 文件,并存储在 Hadoop 集群中的 8 个不同节点上。每个分裂可以复制 3 次,以实现容错,以便如果 1 个节点故障的话,也有备份。HDFS 适用于顺序的“一次写入、多次读取”的类型访问。

不妨新建一个文件夹 -- mnist, 将数据集下载到 mnist 以后, 解压即可:

图片 3

图片 4

MapReduce:一个计算框架。它以分布式和并行的方式处理大量的数据。当你对所有年龄> 18 的用户在上述 1 GB 文件上执行查询时,将会有“8 个映射”函数并行运行,以在其 128 MB 拆分文件中提取年龄> 18 的用户,然后“reduce”函数将运行以将所有单独的输出组合成单个最终结果。

dataset

YARN(Yet Another Resource Nagotiator,又一资源定位器):用于作业调度和集群资源管理的框架。

图片是以字节的形式进行存储, 我们需要把它们读取到 NumPy array 中, 以便训练和测试算法.

Hadoop 生态系统,拥有 15 多种框架和工具,如 Sqoop,Flume,Kafka,Pig,Hive,Spark,Impala 等,以便将数据摄入 HDFS,在 HDFS 中转移数据(即变换,丰富,聚合等),并查询来自 HDFS 的数据用于商业智能和分析。某些工具(如 Pig 和 Hive)是 MapReduce 上的抽象层,而 Spark 和 Impala 等其他工具则是来自 MapReduce 的改进架构/设计,用于显著提高的延迟以支持近实时和实时处理。

import os
import struct
import numpy as np

def load_mnist(path, kind='train'):
    """Load MNIST data from `path`"""
    labels_path = os.path.join(path,
                               '%s-labels-idx1-ubyte'
                               % kind)
    images_path = os.path.join(path,
                               '%s-images-idx3-ubyte'
                               % kind)
    with open(labels_path, 'rb') as lbpath:
        magic, n = struct.unpack('>II',
                                 lbpath.read(8))
        labels = np.fromfile(lbpath,
                             dtype=np.uint8)

    with open(images_path, 'rb') as imgpath:
        magic, num, rows, cols = struct.unpack('>IIII',
                                               imgpath.read(16))
        images = np.fromfile(imgpath,
                             dtype=np.uint8).reshape(len(labels), 784)

    return images, labels

在此我向大家推荐一个大数据技术交流圈: 658558542 突破技术瓶颈,提升思维能力 (☛点击即可加入群聊)

load_mnist 函数返回两个数组, 第一个是一个 n x m 维的 NumPy array(images), 这里的 n 是样本数(行数), m 是特征数(列数). 训练数据集包含 60,000 个样本, 测试数据集包含 10,000 样本. 在 MNIST 数据集中的每张图片由 28 x 28 个像素点构成, 每个像素点用一个灰度值表示. 在这里, 我们将 28 x 28 的像素展开为一个一维的行向量, 这些行向量就是图片数组里的行(每行 784 个值, 或者说每行就是代表了一张图片). load_mnist 函数返回的第二个数组(labels) 包含了相应的目标变量, 也就是手写数字的类标签(整数 0-9).

图片 5

第一次见的话, 可能会觉得我们读取图片的方式有点奇怪:

Q2.为什么组织从传统的数据仓库工具转移到基于 Hadoop 生态系统的智能数据中心?

magic, n = struct.unpack('>II', lbpath.read(8))
labels = np.fromfile(lbpath, dtype=np.uint8)

Hadoop 组织正在从以下几个方面提高自己的能力:

为了理解这两行代码, 我们先来看一下 MNIST 网站上对数据集的介绍:

现有数据基础设施:

TRAINING SET LABEL FILE (train-labels-idx1-ubyte):

[offset] [type]          [value]          [description] 
0000     32 bit integer  0x00000801(2049) magic number (MSB first) 
0004     32 bit integer  60000            number of items 
0008     unsigned byte   ??               label 
0009     unsigned byte   ??               label 
........ 
xxxx     unsigned byte   ??               label
The labels values are 0 to 9.

主要使用存储在高端和昂贵硬件中的“structured data,结构化数据”

通过使用上面两行代码, 我们首先读入 magic number, 它是一个文件协议的描述, 也是在我们调用 fromfile 方法将字节读入 NumPy array 之前在文件缓冲中的 item 数(n). 作为参数值传入 struct.unpack>II 有两个部分:

主要处理为 ETL 批处理作业,用于将数据提取到 RDBMS 和数据仓库系统中进行数据挖掘,分析和报告,以进行关键业务决策。

  • >: 这是指大端(用来定义字节是如何存储的); 如果你还不知道什么是大端和小端, Endianness 是一个非常好的解释. (关于大小端, 更多内容可见<<深入理解计算机系统 -- 2.1 节信息存储>>)
  • I: 这是指一个无符号整数.

主要处理以千兆字节到兆字节为单位的数据量

通过执行下面的代码, 我们将会从刚刚解压 MNIST 数据集后的 mnist 目录下加载 60,000 个训练样本和 10,000 个测试样本.

基于 Hadoop 的更智能的数据基础设施:

为了了解 MNIST 中的图片看起来到底是个啥, 让我们来对它们进行可视化处理. 从 feature matrix 中将 784-像素值 的向量 reshape 为之前的 28*28 的形状, 然后通过 matplotlib 的 imshow 函数进行绘制:

其中结构化,非结构化(例如 images,PDF,docs )和半结构化(例如 logs,XMLs)的数据可以以可扩展和容错的方式存储在较便宜的商品机器中。

import matplotlib.pyplot as plt

fig, ax = plt.subplots(
    nrows=2,
    ncols=5,
    sharex=True,
    sharey=True, )

ax = ax.flatten()
for i in range(10):
    img = X_train[y_train == i][0].reshape(28, 28)
    ax[i].imshow(img, cmap='Greys', interpolation='nearest')

ax[0].set_xticks([])
ax[0].set_yticks([])
plt.tight_layout()
plt.show()

可以通过批处理作业和近实时(即,NRT,200 毫秒至 2 秒)流(例如 Flume 和 Kafka)来摄取数据。

我们现在应该可以看到一个 2*5 的图片, 里面分别是 0-9 单个数字的图片.

数据可以使用诸如 Spark 和 Impala 之类的工具以低延迟(即低于 100 毫秒)的能力查询。

图片 6

可以存储以兆兆字节到千兆字节为单位的较大数据量。

0-9

这使得组织能够使用更强大的工具来做出更好的业务决策,这些更强大的工具用于获取数据,转移存储的数据(例如聚合,丰富,变换等),以及使用低延迟的报告功能和商业智能。

此外, 我们还可以绘制某一数字的多个样本图片, 来看一下这些手写样本到底有多不同:

Q3.更智能&更大的数据中心架构与传统的数据仓库架构有何不同?

fig, ax = plt.subplots(
    nrows=5,
    ncols=5,
    sharex=True,
    sharey=True, )

ax = ax.flatten()
for i in range(25):
    img = X_train[y_train == 7][i].reshape(28, 28)
    ax[i].imshow(img, cmap='Greys', interpolation='nearest')

ax[0].set_xticks([])
ax[0].set_yticks([])
plt.tight_layout()
plt.show()

传统的企业数据仓库架构

执行上面的代码后, 我们应该看到数字 7 的 25 个不同形态:

图片 7

图片 8

基于 Hadoop 的数据中心架构

7

图片 9

本文由mgm娱乐网址发布于mgm娱乐网址,转载请注明出处:允许你以一种分布式和冗余的方式存储大量数据

关键词: