异步数据存储声明

时间:2022-04-21
本文章向大家介绍异步数据存储声明,主要内容包括异步访问、数据是国王、消息和数据处理的混合、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

在过去的几年里,NoSQL数据存储的工作让我对应用程序的方向有了一些见解,因为NoSQL成为了主流的数据存储和检索方法,至少对网络和基于云的程序来说是这样的(企业级应用最终也会这样,但这需要花费较长的时间)。多年来,我学会了相信自己的直觉,我的直觉告诉我,这种方法很有价值,应该有人去探索——即使我个人没有时间来写这个系统。

异步访问

我认为整个方法的核心是对数据的非阻塞异步访问。一般来说,如果我们希望在程序中使用异步消息传递,就必须获得消息代理的帮助,消息代理的唯一目的就是异步地路由消息。毫无疑问,我最喜欢的就是RabbitMQ。但是,为了扩展RabbitMQ的一些关键功能和抓住特别棘手的部分,我认为通过利用一个更加轻量级的异步库,可以更快地实现更多的进展,这个库不是一个具体的协议,类似RabbitMQ之于AMQP。

在我看来,Node.js已经改变了Web程序开发的形式。虽然真正的异步程序比较难以构建(因此,在一般民众中还没有那么受欢迎。),但在云环境中,用户可能需要大量相对较小的虚拟机实例,这些虚拟机可以相互协作,因此在云环境中,它的可扩展性更强,性能也更好。

我们当然可以在这里使用便利的消息代理,添加一些消费者,在我们的Web程序中写几个生产者,然后说写的不错。

但我不会满足于此。

数据是国王

如果我们将程序剥离为最纯粹的形式,那么我们唯一关心的就只有数据。我可能会选择我最喜欢的NoSQL数据存储和Riak,因为它们既可以扩展我的数据,我又可以在我的数据上执行分布式的Map / Reduce。但是,首先,数据才是程序的全部原因。无论我在程序内部做什么都是在有数据的环境中完成的。如果我使用消息代理,那么消息就是数据。如果我建立一个网络表单,我将接收数据。如果我生成报告,我将报告数据。

没有什么比数据更重要。

但是消息代理不关心数据,它仅仅是一个指挥,消息存储并不关心这个指挥。但事实并非如此。

因为我认为在代码中,也许有一个例子可以说明我的观点。

想象一下,我需要将上传的图像转换成缩略图。要做到这一点,我写了一个简单的程序,使用ImageMagick缩放,裁剪,并将图像转换为JPEG。我还创建了一个Web窗体,允许用户上传他们的图像。在这个异步的数据存储世界中,我的图像转换器逻辑应该能够监听数据存储中的INSERT或UPDATE事件并将其转换传入数据,自动存储上传图像的缩略图。

图像转换器伪代码:

def db = asyncdb.connect("tcp://localhost:5555") 
def img = request.get_upload_data("image") 
def metadata = [ content_type: "image/jpg" ] 
db.push("imagebucket", img.name, img.data, metadata, { event, data -> 
  if(event.type == SUCCESS) { 
    db.push("profilebucket", "$user.profile", [ avatar: data.key + ".thumbnail" ]) 
  } 
})

这是什么:

  • 连接到数据存储的节点。
  • 通过传递可以调用的Closure来订阅数据存储事件,返回true | false并在过滤器Closure返回true时传递Closure来调用。
  • 被调用时,会自动更新缩略图,并将原始图像的版本存储在特定的键下。

在我的Web程序控制器中,我通过使用异步数据存储访问客户端插入上传的图像。

def db = asyncdb.connect("tcp://localhost:5555", [ name: "image.converter", 
                                            description: "Image thumbnailing listener" ])

这是什么:

  • 连接到数据存储的节点。
  • 构建新的数据存储条目,包括可以触发缩略图侦听器的元数据。
  • 异步地将图像数据“推入”数据存储区并注册一个事件处理程序,以便在监听程序成功缩略图像时调用客户机的回调函数。
  • 当缩略图成功创建后,用户的配置文件将通过向其中添加新的数据进行更新,该数据引用了新转换的缩略图。

注意,这一切都是以非阻塞和异步的方式完成的。数据完整性保持不变,因为直到缩略图创建完成后才会更新配置文件。这个系统也是无国界的。每个节点彼此都知道,所以负载平衡器可以将请求的第一部分发送到一个服务器,将请求的第二部分发送到另一个服务器,但是没有一个是重要的,因为一个操作依赖于另一个等待被释放的特定事件。

消息和数据处理的混合

这种数据访问形式对我来说很有意义。虽然它可能混合了一些传统上没有一起使用过的程序(异步消息传递和数据存储),但它可以创造出非常简洁和易于理解的应用程序。

数据存储应该提供一个Web UI,以便开发人员可以询问系统的内部,看看事件是否正在等待交付。在理想情况下,客户端方法也应该接收Web UI向开发人员展示的任意元数据,以便他们可以很容易地看到报告监听器实际上做了什么。如下所示:

def db = asyncdb.connect("tcp://localhost:5555", [ name: "image.converter", 
description: "Image thumbnailing listener" ]) 

目前没有任何数据存储支持这些类型的东西。可能是我是唯一真正喜欢这种东西的人。但是随着数据访问渐渐走向有更多异步和NoSQL的世界,我们的应用程序开发模式将发生变化。我可以向你保证。唯一的问题是“它会改变什么?”