位置跟踪器pt。 2:扩展“每个用户的数据库”模式

想要将您的应用程序扩展到数百万用户,同时保持将私有信息安全可靠地(轻松地!)同步到Cloudant的能力吗? 在本教程中,我们将向您展示如何进行。

在“位置跟踪器”(第1部分)中,我们向您展示了如何创建一个iOS应用程序来跟踪您的位置,与Cloudant同步以及执行地理位置查询以查找附近的兴趣点。 我们向您展示了如何使用每用户数据库设计模式来利用Cloudant强大的同步功能,同时确保用户的位置信息保持私有。 我们还讨论了“每用户数据库”设计模式如何适合中小型应用程序,但是当您希望扩展到数百万个用户时,效果不那么理想。 在本教程中,我们将向您展示如何扩展Location Tracker来做到这一点。

复习

Location Tracker应用程序是在Swift中开发的iOS应用程序,可跟踪用户位置并将这些位置同步到Cloudant。 当用户移动并记录新位置时,该应用会查询服务器以获取用户位置附近的兴趣点。

以下是“位置跟踪器”应用的屏幕截图。 蓝色图钉标记应用程序记录的每个位置。 在用户行进的路径上绘制了一条蓝线。 每次Location Tracker应用程序记录新位置时,都会在Cloudant中执行基于半径的地理查询,以查找附近的兴趣点(在应用程序中称为“地点”)。 半径由绿色圆圈表示。 位置显示为绿色图钉。

在第1部分中,我们确定了Location Tracker应用程序的五个关键要求:

  1. 跟踪前景和背景中的位置。
  2. 使用地理空间查询来查找指定半径内的兴趣点。
  3. 离线运行。
  4. 将用户位置信息保密。
  5. 提供合并和分析所有位置的功能。

为了满足要求#4和#5,我们实现了每个用户数据库的设计模式。 这是学习如何使用Cloudant Sync同步个人或私有数据的重要第一步,但是当扩展到数百万甚至数万个用户时,此设计会出现问题。 Glynn Bird在这篇文章中指出了使用每个用户数据库模式进行扩展的一些问题:

  • 备份-如何为数百万甚至数千个数据库设计备份和还原计划?
  • 报告-您如何在数百万个数据库中生成报告?
  • 变更控制-如何在数百万个数据库中传播数据更新?

为了帮助提供针对这些问题(以及更多问题)的解决方案,一组IBM员工构建了Cloudant Envoy。

Cloudant Envoy FTW!

Cloudant Envoy是一种微服务,可充当您的PouchDB Web应用程序或基于Cloudant Sync的本机应用程序的复制目标。 Envoy允许您的客户端代码采用“每个用户一个数据库”的设计模式,将用户数据的副本存储在移动设备上,并在联机时同步到云中,同时将所有用户的数据无形地存储在一个大空间中。数据库。 这样可以防止在添加用户时发生的数据库激增,并简化备份和服务器端报告。

这就是在GitHub上描述Cloudant Envoy的方式。 让我们分解一下此描述,并解压缩Location Tracker的相关点:

Cloudant Envoy是一种微服务,可充当您的PouchDB Web应用程序或基于Cloudant Sync的本机应用程序的复制目标。

在第1部分中,我们展示了Location Tracker iOS应用如何针对Cloudant中特定于用户的数据库进行复制。 在本教程中,我们将展示iOS应用如何(甚至不知道)如何针对Cloudant Envoy。

Envoy允许您的客户端代码采用“每个用户一个数据库”的设计模式,将用户数据的副本存储在移动设备上,并在在线时同步到云中。

从一开始,Location Tracker iOS应用就是使用每用户数据库设计模式构建的。 每个用户的位置都存储在本地的iOS设备上,并在联机时同步到Cloudant。 复制到Envoy时,这不会改变。 实际上,iOS应用程序需要零更改才能支持Envoy。

…同时将所有用户的数据不可见地存储在一个大型数据库中。 这样可以防止在添加用户时发生的数据库激增,并简化备份和服务器端报告。

使用Cloudant Envoy,我们可以将所有私有位置数据存储在一个数据库中。 这使后端开发人员或数据科学家可以更轻松地处理数据,并解决了我们提到的每个用户数据库模式中的三个问题:备份,报告和变更控制。

建筑

在第1部分中,我们实现了每个用户的数据库设计模式,并为每个用户创建了一个数据库来跟踪该用户的位置。 这是我们的架构图:

用户注册和地理查询是通过在IBM Bluemix上运行的Node.js应用程序执行的,而位置则直接同步到了Cloudant中特定于用户的数据库。 用户特定的数据库已配置为复制到集中式数据库以存储所有位置。 使用Cloudant Envoy,我们的架构大大简化了:

在第2部分中,仍然通过自定义Node.js应用程序执行用户注册和地理查询,但是现在所有位置复制都通过Envoy进行路由并存储在单个集中式数据库中。 我们不再直接连接到Cloudant。 我们不再需要为每个用户创建数据库,也不必配置从这些数据库到集中式位置数据库的复制,并且我们继续满足我们的要求,包括:

  • 将用户位置信息保密 -由Envoy完全处理。 用户只能访问自己的位置。
  • 提供整合和分析所有位置的功能 -默认情况下,使用Envoy,所有位置都存储在同一数据库中。 无需复制或数据复制。

新服务器

在第1部分中,我们讨论了Location Tracker Server,这是一个Node.js应用程序,它提供RESTful API,用于使用Cloudant Geo注册新用户和查询位置。 在本教程中,我们创建了一个新服务器来执行这些功能并配置对Cloudant Envoy的支持。 该服务器称为位置跟踪器Envoy服务器。

当您安装Location Tracker Envoy Server时,将在您的Cloudant实例中创建三个数据库:

  1. envoyusers –服务器和Cloudant Envoy使用此数据库来管理和认证用户。
  2. lt_locations_all_envoy此数据库用于跟踪通过Envoy从iOS设备同步到Cloudant的所有位置。
  3. lt_places –此数据库包含“位置跟踪器”应用程序将查询的位置列表。

遵循Location Tracker Envoy Server GitHub页面上的指示信息,以获取Location Tracker Envoy Server并在本地或Bluemix上运行。

同一客户

如前所述,iOS应用程序需要零更改以支持与Envoy同步。 iOS应用在登录时被指定了位置复制目标。 Envoy是Cloudant复制的直接替代品。 服务器将路径返回到Envoy实例,而不是将路径返回到特定于用户的数据库进行复制。

设置位置跟踪器Envoy服务器后,请按照位置跟踪器应用GitHub页面上的说明进行操作,以在Xcode中启动并运行位置跟踪器应用。

怎么运行的

在本教程的其余部分,我们将提供有关如何使用Envoy的更多详细信息。 有关应用程序如何跟踪位置或兴趣点的更多信息,请参阅第1部分。本教程重点介绍Cloudant Envoy以及对后端所做的更改以支持Envoy。

用户注册

Cloudant Envoy有几种不同的选项来管理用户。 您可以配置与ENVOY_AUTH环境变量一起使用的方法。 必须在Bluemix中的Cloudant Envoy应用程序和Location Tracker Envoy Server应用程序上都设置此变量。 有关可用的不同身份验证选项的更多信息,请参阅Cloudant Envoy文档。

默认情况下,用户存储在名为envoyusers的数据库中。 第1部分极大地简化了用户注册过程。从iOS应用发送了相同的PUT请求:

  { 
“用户名”:“ markwatson”,
“ password”:“ passw0rd”,
“类型”:
“用户”,
“ _id”:“ markwatson”
}

但是,此请求的后端处理要简单得多。 以前,后端将创建新数据库,设置API密钥和密码,并配置新数据库和集中位置数据库之间的连续复制。 当新的Node.js服务器收到PUT请求时,将执行以下步骤:

  1. 检查用户是否存在指定的ID。 如果用户已经存在,则将状态409返回给客户端。
  2. 将用户及其ID和密码(哈希)存储在用户数据库中。

而已!

用户登录

注册后,用户立即登录。 同样,未对iOS应用进行任何更改。 该应用程序将以下请求发送到Node.js服务器:

  { 
“用户名”:“ markwatson”,
“ password”:“ passw0rd”
}

服务器以与服务器先前版本相同的格式答复:

  { 
“ ok”:是的,
“ api_key”:“ markwatson”,
“ api_password”:“ passw0rd”,
“ location_db_name”:“ lt_locations_all_envoy”,
“ location_db_host”:“ cloudant-envoy-XXXX.mybluemix.net”
}

这里的动机是向后兼容。 该应用程序希望接收要同步的API密钥,密码,数据库和主机。 在第1部分中,这是用户特定的数据库,但是如您现在所见,服务器正在发送与Envoy同步所需的信息。 api_keyapi_password字段现在将用户的用户名和密码作为其值。 这是Envoy所期望的,并且通过使用这种格式,代码保持了与第1部分中的服务器的向后兼容性。相应地,旧的按用户数据库模式中的唯一值( location_db_namelocation_db_host )现在采用标准化值: "lt_locations_all_envoy"和Envoy主机。

同步位置

客户端和服务器之间的同步位置未更改。 Envoy实现了与Cloudant相同的复制协议,从而使迁移对客户端完全透明。 位置跟踪器应用程序使用Cloudant Sync for iOS与Envoy进行同步,其方式与直接同步到Cloudant的方式完全相同。

数据

当数据全部存储在同一数据库中时,Envoy如何知道谁拥有数据? Envoy可以通过几种不同的方式来识别谁拥有数据,但是在每种情况下都应用相同的原理:

  1. 保存新位置时,请更改数据以包括经过身份验证的用户信息。
  2. 检索位置时,请使用经过身份验证的用户信息来过滤数据。

Envoy修改进出的每个文档,并过滤出进的每个文档。 Envoy提供了用于向数据添加所有权信息的不同选项。 可以通过在Cloudant Envoy中设置ENVOY_ACCESS环境变量来配置这些选项。 有关更多信息,请参阅Cloudant Envoy文档。

默认情况下,Envoy将文档的所有权存储在文档的_id字段中。 它将用户名的sha1哈希添加到ID之前。 这是一个示例文件:

  { 
“ _id”:“ c00268ec8506774f20229f1eb9142e0d1f1a938b-014144EE-25BB-4251-94AC-A7BBD3C04CB5”,
“ _rev”:“ 1-8801d4d9a3bf8a539692af9697b89eb5”,
“ created_at”:1468251203669.592,
“几何”:{
“ type”:“ Point”,
“坐标”:[-122.39203496,37.5668706]
},
“属性”:{
“时间戳记”:1468251203669.592,
“ username”:“ envoy_user1”,
“背景”:false
},
“ type”:“功能”
}

该文档存储在envoy_user1 。 Envoy存储的每个envoy_user1文档都将带有一个_id前缀为c00268ec8506774f20229f1eb9142e0d1f1a938b

差异Part1 Part2

总而言之,让我们与“位置跟踪器”的第1部分进行比较,以查看我们为帮助扩展解决方案而进行的重大更改:

  • 仅在第1部分中 -为每个用户创建新数据库。
  • 仅在第1部分中 —配置每个特定于用户的数据库与统一位置数据库之间的复制。
  • 仅在第1部分中 -告诉iOS应用程序直接同步到Cloudant中用户特定的数据库。
  • 仅在第2部分中 -告诉iOS应用与Cloudant Envoy同步。
  • iOS App-不变。

Cloudant可以扩展,但是无法为数百万个用户创建数百万个数据库。 Cloudant Envoy将您的私人数据存储在单个数据库中,该数据库可以扩展以支持数百万个用户,同时还使您可以充分利用Cloudant Sync的所有优势。 使用Cloudant Envoy,我们不仅提高了扩展能力,而且还简化了解决方案的几乎每个方面。

结论

在本教程中,我们展示了如何使用Cloudant Envoy将Cloudant的数据复制和同步功能扩展到数百万的移动用户。 我们向您展示了Cloudant Envoy如何为Cloudant复制提供直接替代,从而使您可以安全地将私有位置信息同步到单个统一数据库中。

Cloudant Envoy仍处于测试阶段,但我们对其潜力感到非常兴奋,并敦促您立即开始尝试。 有关位置跟踪器和Cloudant Envoy的更多信息,请参见以下链接:

Interesting Posts