### 架构
对于开发者来说,Redis因为其性能上的优势往往会被采用作为位置数据的缓存,只是在3.2版本之前需要代码中把位置数据进行Geohash后才能有效的排序和分析。不过3.2版本后,Redis已经能够原生支持基于位置信息的存储,计算及搜索了。Amazon ElastiCache是AWS提供的托管型的数据缓存服务,借助该服务,用户能够在云中轻松部署、运行和扩展分布式内存数据存储或缓存。 Amazon ElastiCache 的Redis引擎是一项与 Redis 兼容的内存服务,兼具 Redis 的易用性和强大功能,同时还可为要求最苛刻的应用程序提供适用的可用性、可靠性和性能,提供单节点和多达 15 个分片的群集,从而可将内存数据扩展到高达 3.55TiB。这里,我们可以基于Elasticache并结合AWS其他服务构建出以下的示例架构:
[](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/20/20170721-1-1024x717.png)](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/20/20170721-1.png)
1)终端设备获取GPS位置信息,定时或基于事件将数据上传到云端。在AWS上可以选择使用IoT或Kinesis等托管型服务作为数据收集的接收端,也可以使用部署在EC2/Lambda上的自定义服务。
2)所有位置信息写入可以自动扩展的DynamoDB,基本Schema包含设备Id/Timestamp/Geo location, 方便历史查询或轨迹查询。
3)打开DynamoDB流,用KCL或Lambda监听DynamoDB的数据改变,并将当前变化的位置数据更新到Elasticache中建立基于Geospatial的索引缓存。
4)手机应用搜索附近资源时,部署在EC2/Lambda的查询服务利用Elasticache geospatial直接获取结果。
### 实现
如前文所述,步骤1和2可选择的方案很多,比如采用AWS IoT服务甚至可以无需任何代码仅通过配置即可完成云端的功能讲数据实时写入相应的DynamoDB表中。因此,本文将着重介绍如何实现前文架构中的3和4步:
a) 打开DynamoDB 流,获取流的ARN用于读取,如下图:
[](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/20/20170721-2-1024x662.png)](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/20/20170721-2.png)
读取DynamoDB流数据有三种方式:利用Kinesis adapter,利用低级别API以及利用Lambda函数来进行读取。从易用性的角度来说,当然是Lambda函数最简单,不需要考虑shard,吞吐和checkpoint等问题而专注于业务逻辑。但是Lambda函数并不是在所有的AWS区域都支持,因此本文采用第一种方式利用Kinesis adapter完成读取。具体参考文档:http://docs.amazonaws.cn/amazondynamodb/latest/developerguide/Streams.KCLAdapter.html
b) 在读取流的同时,我们需要将最新的地理位置信息利用GEOADD更新到Elasticache中。前文提到Redis在3.2版本后,Geospatial Indexing已经被原生支持,而它实际上是Sorted List数据结构的一种扩展,即排序 key扩展成了经纬度,如下图所示的数据结构,并且可以方便的使用基于地理信息的API,例如GEOADD——添加地理位置 。
[](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/20/20170721-3-1024x204.png)](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/20/20170721-3.png)
通过Elasticache可以快速构建出一个Redis环境,包括支持shard的集群模式,如下图所示。
[](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/20/20170721-4.png)](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/20/20170721-4.png)
构建完成后,通过Elasticache提供的终端节点就可以访问cache了。
[](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/20/20170721-5.png)](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/20/20170721-5.png)
需要注意的是如果选择的Redis是集群模式,那么就得同步升级支持Redis集群模式的客户端SDK用以开发。因为Redis的集群提供的是分片功能,它会把不同的slots分布在不同的节点上,需要由客户端通过CRC16(Key)取模从而计算出数据在哪个节点上。目前可以支持redis集群模式的客户端有很多,比如本文用到的java的jedis以及nodejs的ioredis。
综合a,b两步的示例代码的StreamCacheProcessor.java如下(其余代码参考http://docs.amazonaws.cn/amazondynamodb/latest/developerguide/Streams.KCLAdapter.Walkthrough.CompleteProgram.html ):
Java
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import redis.clients.jedis.GeoCoordinate
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import com.amazonaws.services.dynamodbv2.streamsadapter.model.RecordAdapter;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessor;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessorCheckpointer;
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.ShutdownReason;
import com.amazonaws.services.kinesis.model.Record;
public class StreamsCacheProcessor implements IRecordProcessor {
private static Log LOG = LogFactory.getLog(StreamsCacheProcessor.class);
private Integer checkpointCounter;
private String clusterHost;
private int port;
private JedisCluster jedis;
public StreamsCacheProcessor(String clusterHost,int port) {
this.clusterHost=clusterHost;
this.port=port;
}
@Override
public void initialize(String shardId) {
Set jedisClusterNode=new HashSet();
jedisClusterNode.add(new HostAndPort(clusterHost,port));
jedis=new JedisCluster(jedisClusterNode);
checkp ointCounter = 0;
}
@Override
public void processRecords(List records, IRecordProcessorCheckpointer checkpointer) {
for (Record record : records) {
String data = new String(record.getData().array(), Charset.forName("UTF-8"));
LOG.debug("Received the data as:"+data);
if(record instanceof RecordAdapter)
com.amazonaws.services.dynamodbv2.model.Record streamRecord = ((RecordAdapter) record).getInternalObject();
//新增GPS数据更新到Elasticache中
if(streamRecord.getEventName().equals("INSERT")){
Map coordinateMap = new HashMap();
double longitude = Double.parseDouble(streamRecord.getDynamodb().getNewImage().get("longitude").getN());
double latitude = Double.parseDouble(streamRecord.getDynamodb().getNewImage().get("latitude").getN());
String deviceId = streamRecord.getDynamodb().getNewImage().get("deviceId").getS();
coordinateMap.put(deviceId, new GeoCoordinate(longitude, latitude));
jedis.geoadd("bikes", coordinateMap);
LOG.info("Updated "+deviceId+" GPS information as:"+longitude+","+latitude);
}
}
checkpointCounter += 1;
if(checkpointCounter % 10 == 0){ //checkpoint大小需根据实际需求调整
try {
checkpointer.checkpoint();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
@Override
public void shutdown(IRecordProcessorCheckpointer checkpointer, ShutdownReason reason)
{
if(reason == ShutdownReason.TERMINATE) {
try {
checkpointer.checkpoint();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
c)在完成地理信息的实时更新后, 可以基于Elasticache的数据利用GEORADIUS搜索周边的资源。使用nodejs示例代码如下:
Java
var express = require('express');
var app = express();
var Redis = require('ioredis');
var cluster = new Redis.Cluster([{
port:6379,
host:'lab-cluster.4bh9j8.clustercfg.cnn1.cache.amazonaws.com.cn'
}]);
app.get('/bikes', function(req,res){
if(req.query['longitude'] && req.query['latitude']){
console.log ('longitude = %s,latitude = %s',req.query['longitude'],req.query['latitude']);
cluster.send_command('GEORADIUS',
[ 'bikes',req.query['longitude'],req.query['latitude'],2000,
'm',
'WITHDIST',
'WITHCOORD',
'COUNT',
10], (error, reply) =>{
if (error) {
res.status(500).send("无法获取附近车辆信息");
return;
}
var stations = reply.map( (r) =>{
return {
name: r[0],
distance: `${r[1]} m`,
coordinates: {
latitude: Number(r[2][1]),
longitude: Number(r[2][0])
} }
});
res.status(200).json(stations);
});
}
});
var server = app.listen(8080,function(){
var host = server.address().address
var port = server.address().port
console.log("应用实例,访问地址为 http://%s:%s", host, port)
});
基于以上代码,服务端就可以返回最近的10个资源以及每个资源离当前位置的距离。例如:
请求
`http://hostname or elb address/bikes?longitude=116&latitude=39.4`
返回
Java
[
{
"name": "48093ba0-f8f1-49f0-b312-285800341b08",
"distance": "1117.8519 m",
"coordinates": {
"latitude": 39.40640623614937,
"longitude": 116.01002186536789
}
},
{
"name": "950fb5df-c0ff-4a95-90ea-2f5f574c5796",
"distance":"1305.5083 m",
"coordinates": {
"latitude": 39.40184880750488,
"longitude": 116.01500004529953
}
},
……
]
d)通过封装http请求构建手机应用。
[](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/08/01/map-503x1024.png)](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/08/01/map.png)
### 总结
Redis Geospatial功能可以让开发者更高效的搜索和计算位置信息的记录。同时,Amazon ElastiCache提供的托管Redis服务大大简化了对于Redis集群的维护工作,包括搭建,备份和迁移等工作。最后,自动扩展的Amazon DynamoDB则负责位置信息数据的持久化和检索,而它的流功能也使得数据能够快速实时的流转起来。
**作者介绍**
[](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/24/Zhao-Fei-Mini.png)](https://d2908q01vomqb2.awsstatic-china.com/472b07b9fcf2c2451e8781e944bf5f77cd8457c8/2017/07/24/Zhao-Fei-Mini.png)
赵霏,AWS解决方案架构师。负责基于AWS的云计算方案架构咨询和设计,同时致力于AWS云服务在国内的应用和推广。他拥有超过13年IT行业从业经验,长期专注于企业IT云转型、物联网、移动互联网、Devops等领域,在大规模后台架构、分布式计算和自动化运维等方面有着广泛的设计和实践经验。
本文转载自 AWS 技术博客。
原文链接:
https://amazonaws-china.com/cn/blogs/china/using-amazon-elasticache-to-find-x/
更多内容推荐
35|行业:如何在一周内快速了解一个行业?
在工作之后有兴趣去了解新的行业,不仅仅只是工作需求,也是更大的风险对冲。
2022-10-28
区块链将在元宇宙旅游中发挥哪些价值?
在疫情催化下,人类社会生活的数字化转型进程全面加速。网络直播、短视频、云看展云旅游,各种各样的数字化旅游形态逐渐兴起。数字文旅产业也越来越被各地政府作为推动产业高质量发展的重要抓手,借助相关政策和5G、大数据、AR、VR、云计算等技术,成为文旅行
2021-12-24
21|广告产品彩蛋:课程答疑与推荐书目
铛铛铛,三个彩蛋
2022-04-15
09|语义检索,利用 Embedding 优化你的搜索功能
语义检索,利用Embedding优化你的搜索功能
2023-04-03
架构师训练营 - 大作业: 物流系统架构设计
通达物流系统是一个解决同城用户与快递员快速寄件/取件、下单/抢单、支付/提现、综合查询的物流系统。
2021-01-27
导航网站合集 | 你想要的资源它都有
导航网站有很多,至于哪个好用因人而异,有的侧重设计类,有的侧重技术类,有的侧重学术资源,有些则是杂七杂八;这次分享给大家平时小编常用的几大导航网站,汇聚了几乎各领域的专业网站,只有你想不到,没有你找不到。
2022-05-07
记一次勒索病毒后的应急响应
群晖是一种NAS(网络附属存储)系统,在生活中主要扮演个人私有云角色,可以将文件存储于 NAS,并通过网页浏览器或手机应用程序可实现存储和共享,同时还提供的丰富应用以方便管理应用。借助群晖提供的 QuickConnect 快连服务,无需随身携带存储设备,即可以
2021-08-21
150 个超实用的网站,整理成资源库页面分享给大家
我将这些资源分为七大类:学习资源、图片资源、办公资源、娱乐资源、设计资源、搜索资源、工具资源,点击相应的分类可以跳转到该分类下,可以方便快捷的找到你想要的资源网站。
2021-11-10
数据库索引相关和 EFCore 的索引映射
索引用于快速找出在某个列中有某一特定值的行,不使用索引,数据库必须从第一条记录开始读完整个表,直到找出相关的行。表越大,查询数据所花费的时间越多, 如果表中查询的列有一个索引,数据库能快速到达一个位置去搜索数据。
2022-11-21
协同过滤:你看到的短视频都是集体智慧的结晶
在实际算法的应用过程当中,还有一种通过集体智慧来构成的复合算法,它可以寻找大量人群当中的行为数据模型规律,达成普通算法从单体上无法达到的效果。这种算法当中,最著名的一个算法就是协同过滤算法。
2021-09-10
【前端 · 面试 】HTTP 总结(七)—— HTTP 缓存概述
HTTP 缓存指的是: 当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源。
2021-08-07
18|规则:豌豆荚做不起来应用内搜索?
可能互联网世界不多一个的91助手,但是缺一个豌豆荚。
2022-08-29
升级 HarmonyOS 2 最新版本,出门亮健康码快人一步!
最近一段时间,在人口流动较大的大城市疫情反复,防疫形势紧张,商场、地铁站、公交、餐厅、办公楼、小区等场所都要求出示健康码、行程卡,甚至核酸检测报告才能进入。然而,我们都知道,打开健康码的步骤并不简单,需要先点击微信/支付宝,再搜索健康码小程
2022-05-09
去哪儿网库存搜索在高并发场景下的探索
Qunar机票作为核心业务之一,每天都有成千上万用户在Qunar平台上完成搜索预定生单等操作。在机票业务中,有一类特殊的产品是通过库存进行管理的,这里的一个库存就对应飞机上的一个座位,本次分享会重点介绍这方面我们的思考和做的工作。
2021-08-30
HashMap 源码解析,Java 黑马程序员资源
*/
2021-08-06
一篇文章告诉你 GIS 存储如何选?
地理信息系统(Geographic Information System,GIS)又称为“地学信息系统”或“资源与环境信息系统”,是以地理空间数据为基础,采用地理模型分析方法,适时地提供多种空间的和动态的地理信息,在计算机硬、软件系统支持下,对整个或部分地球表层(包括大气
2021-06-21
技术强、资源多,华为云等保合规解决方案助力企业快速过等保!
技术强、资源多,华为云等保合规解决方案助力企业快速过等保!
2022-10-21
知道这个网站你就不用买实体书了
少即是多, 网上找书我们也只要知道1个网站!上链接↓ 熊猫搜书 熊猫搜书,电子书导航,电子书资源聚合网站,你想要的书都能找到。
2022-12-14
Elasticsearch 分布式搜索引擎的基本使用
在开发项目中一般都会有搜索功能。如果是面向C端的搜索功能,往往都特别考验性能。比如普通的商城系统中的商品搜索或者一些资源的站内搜索。
2023-05-12
推荐阅读
23. 合理化发挥作用的资源和货币化
2023-10-17
小红书、携程统统靠边站,Google Gemini 打造个性化旅游新体验
10|极具吸引力的 PPT 封面设计
2023-09-03
快上车,搭乘 HUAWEI HiCar 驶向未来
2023-06-28
8 个优秀好用的渠道,帮你找到所想要的资源
2023-06-28
36. 搜索中心
2023-09-30
2024 年中国(南京)国际生活用纸及造纸设备展会
2023-10-22
电子书
大厂实战PPT下载
换一换 吉妙通 | 金山办公 移动端研发总监
邓艳琴(Clara) | 极客邦科技 会议主编
黄武伟 | 小米 AI 实验室 大模型算法工程师
评论