使用Go构建高扩展性房地产房源系统

本文探讨了如何使用Go语言构建高扩展性的房地产房源系统,重点解析了RETS和RESO数据标准的差异,以及如何应对MLS数据源的不一致性,实现高效的数据同步与处理。

使用Go构建高扩展性房地产房源系统

在高扩展性房地产平台中,真正的挑战不仅仅是获取房源信息,还包括以高速、弹性和成本效益的方式处理和提供来自不同MLS(多重上市服务)提供商的数百万条记录。无论您是与美国的BrightMLS还是加拿大的TRREB集成,每个MLS都有其独特之处:不同的数据模型、不一致的元数据、不规则的更新周期和不断演变的模式。

在规模上,这些差异不再是边缘情况,而是日常障碍。您的后端不仅需要摄取和规范化数TB的房源数据,还需要应对实时同步、去重、标记、评分和高级过滤,且无瓶颈。对于我们温哥华一家高增长房地产初创公司的团队来说,解决方案是使用Go(Golang)设计一个系统,该系统能够容忍高并发、具有严格的内存限制,并在实际生产压力下运行。

为了在这种混乱中建立某种秩序,行业机构开发了RETS(房地产交易标准),以及更近期的RESO(房地产标准组织)。RETS是数据交换标准化的真诚努力,而RESO则通过使用RESTful API和集中式数据字典更进一步。然而,标准采用仍不完整,处理原始MLS数据仍然需要强大的规范化层、模式灵活性和领域特定推理。

本文是一个更详细系列的第一部分,该系列将带您了解我们的系统设计决策、开发实践和基于Go的架构,以解决这些问题。在本文中,我们首先解构核心标准RETS和RESO Web API,不是作为历史,而是作为后续内容的必要前提。

房地产数据标准:RETS、RESO和对一致性的追求

构建可扩展房地产房源基础设施中最持久的问题之一是处理不同MLS提供商之间的数据不一致性。尽管行业已经尝试引入标准措施,但实际情况远非统一。解决这个问题的两个主要尝试是RETS和RESO,每个都提供了一个同质化的愿景,但在现实中只实现了一半。

房地产交易标准(RETS)大约在2000年代初出现,旨在对访问MLS数据施加秩序。它使用XML并拥有自己的查询语言,允许比之前基于FTP的平面文件方法更动态地提取数据。在当时,RETS是真正的进步。然而,随着时间的推移,它难以维护。实现非常多样化,服务器之间的不一致成为常态。此外,XML负载沉重且笨拙,缺乏标准认证机制导致摩擦。随着新Web标准的引入,RETS开始显得过时和僵化,特别是对于必须处理JSON和RESTful API的工程师。

考虑到这些限制,房地产标准组织(RESO)引入了RESO Web API作为RETS的替代方案。这个新规范利用现代Web约定,使用JSON结构化数据,OAuth 2.0进行认证,OData进行查询。目标是拥有更开放的房地产数据,对开发人员友好且可塑。理想情况下,RESO为MLS数据提供了一个不那么笨重且更标准化的接口。实际上,采用不平衡。大多数MLS提供商在实施或发布仅部分符合RESO标准的API方面落后。即使是那些声称符合RESO的提供商也有不同的字段定义、命名约定和可用的元数据。这种理论标准与实际实施经验之间的差异在呈现这些数据源时体现。

在我的工作中,我必须集成来自几个主要提供商的数据,包括CREA和MRED。尽管像RESO这样的标准提供了有用的基础,但我们发现为每个提供商构建自定义解析器、转换管道和验证层是必要的。这些组件充当原始不一致数据与我们系统其余部分之间的缓冲区。它们使我们能够维护一致的内部模式并分离上游异常。现实是,在处理破碎和动态数据环境时,没有任何标准可以替代良好的工程实践。

最后,RETS和RESO是长期计划的一部分,旨在对混乱的世界施加秩序。它们不是银弹,但为行业提供了共同的语言和前进的道路。房地产平台创建者需要学习这些标准,但最重要的是,他们需要以弹性和持久性适应其边缘。

RETS vs. RESO

在工程可扩展的房地产房源系统时,核心挑战之一是处理与多重上市服务(MLS)的集成。这些提供商遵循不同的标准,如果您使用Go构建,RETS和RESO之间的对比不仅仅是技术性的,而且是 deeply practical。

RETS(房地产交易标准)是一个较旧的标准,早于当前的RESTful API。它被引入是为了标准化对MLS的访问,但最终成为了多样化实现的宇宙。另一方面,RESO Web API是一个较新的基于JSON的RESTful标准,与当前的服务设计和工具配合良好,特别是在像Go这样的语言中。

作为Go开发人员使用RETS就像逆向工程一台没有手册的旧机器。它使用HTTP摘要认证、XML负载和称为DMQL的查询语言。Go缺乏RETS SDK,因此您要么创建原始HTTP集成,要么使用脆弱的包装器。在Roomvu,当我们开始集成REBGV的RETS源时,我们的第一步是在Go中创建一个自定义微服务,构建DMQL查询并处理RETS元数据。像SqftTotFin或Status这样的列名没有文档记录,即使是他们方面的微小修改也会无声地破坏我们的管道。

我们的服务必须批量请求数据,自行下载媒体,并重试失败的图片下载。最困难的部分不是缺乏SDK支持,而是不一致性。例如,一些房源会返回有效的元数据和零图片,除非我们包含后验证检查,否则我们无法知道。运行时调试成为常态。系统工作,但脆弱。

相反,与RESO集成毫不费力。使用OAuth2认证和标准化的字段名称,构建集成轻而易举。我们定义了一个带有标记字段的Go结构,并直接调用json.Unmarshal。分页、过滤,甚至使用增量同步进行变更跟踪都正常工作。这使我们能够构建强大的同步服务,添加缓存层,并轮询ETag以成功观察更新。

使用RESO,房源规范化层减少了数量级。我们最近与使用RESO的美国提供商集成,将字段命名的命名和结构一致性减少了一半或更多。我们不再需要运行独立的规范化作业来规范化“平方英尺”或“状态”的概念。

尽管有这些好处,RESO采用仍然落后于较老的委员会。RETS仍在使用,通常是因为提供商没有转换或看不到短期收益。对于使用Go的开发人员,这种共存意味着您的系统需要能够同时支持两种范式。我们更愿意将这些封装为通用接口下的单独服务,以便我们可以维护更清晰的边界,同时随着时间的推移将流量转向基于RESO的集成,因为它们被发布。

最后,如果您的业务在多个委员会上活跃,您将需要支持两种标准。RETS将挑战您的工程,而RESO将以便利回报您。在重视清晰性、性能和并发的Go平台上,RESO显然是更好的选择,但RETS是您尚不能放弃的遗产。

RETS基础

RETS旨在标准化MLS系统和第三方软件之间的房地产房源信息传输。尽管许多MLS供应商正在放弃RETS以采用更现代的解决方案,但它仍然深深嵌入大多数旧系统的设计中。因此,了解RETS的工作原理对于构建可扩展房地产市场集成的开发人员仍然至关重要。

在最基本的情况下,RETS是一个基于会话的、XML-over-HTTP协议。与较新的RESTful API不同,RETS会话通过登录启动,返回令牌并通过cookie建立永久访问。认证的开发人员之后可以获取元数据,这些元数据定义了可用的数据结构,从Property或Agent等资源到它们自己的类和字段。这种元数据必须通过编程方式解析,以了解如何构建语法有效的查询或如何解复用响应形式。

RETS最定义性的特征之一是通过其Search端点查询房源数据。一个简单的搜索查询指定一个资源(例如,Property)、一个类(例如,Residential)和一个C风格语法的查询过滤器,例如(Status=|A)以返回活跃房源。响应以紧凑或完整XML形式,开发人员应能够支持两者,取决于MLS服务器设置。

增量同步是另一个基本RETS概念。客户端可以使用ModificationTimestamp等字段仅下载自上次运行以来更改的房源,从而提供高效的同步。RETS还支持媒体下载,除了房源信息。这是通过GetObject端点实现的,该端点能够批量下载房源图片、虚拟 tours和其他媒体对象。

组件 描述
登录URL 用于启动会话并检索访问凭据(会话ID、能力URL)的端点。
登出URL 用于终止会话并清理服务器端状态。
搜索 核心端点以查询房源数据。需要查询参数并处理分页、格式和约束。
获取元数据 用于检索数据模式的元数据(例如,字段、资源、查找值)。
获取对象 检索多媒体,如图片、文档和虚拟 tours for listings。
获取负载列表 一种较少使用的请求类型,允许检索有效数据组合的元数据。
传输协议 通常通过HTTP与基本认证;有状态通信与cookie或头。
会话管理 需要通过登录/登出启动和维护,带有超时和重新认证。
查询格式 RETS查询语言(RQL),一种专有且不太直观的查询语法(例如,(ListPrice=500000-))。
数据格式 通常以紧凑XML或CSV格式交付,需要在使用前转换。
RETS版本 实现因版本(1.8、1.7.2等)而异,影响支持的功能和兼容性。

但RETS不易使用。MLS在使用标准方面极其不一致。字段名称、查找值,甚至元数据模式差异巨大,因此您的代码经常需要极其灵活和可配置。速率限制、会话超时和不一致的服务器行为也是常见的障碍。

尽管RETS本身正在被较新的、以开发人员为中心的替代方案(如RESO Web API)慢慢取代,但它仍然是房地产数据景观的重要组成部分。对于任何 tasked with building an enterprise-scale, stable listings site的工程师,特别是需要与多个MLS提供商交互的工程师,了解RETS的内部工作原理和 quirks 仍然是 brief 的一部分。

拥抱现代趋势:RESO Web API在房地产开发中的应用

随着房地产行业进一步在线发展,RESO Web API是RETS的数字替代品,提供了一个更互操作、可扩展和开发人员友好的访问多个MLS系统的时代。房地产标准组织(RESO)开发并维护这个API标准,以提供一种更RESTful、安全和一致的方法来访问不同MLS系统上的房地产数据。

在其核心,RESO Web API依赖于开放Web标准,如REST、OData和JSON。这立即降低了开发人员的门槛,他们现在可以放心使用熟悉的模型,如基于URL的资源访问、HTTP动词和无状态架构来进行集成。从RETS到RESO Web API的转变不仅仅是技术升级;它是对一致性、可扩展性和性能的拥抱。

OData的力量

RESO Web API的另一个特点是其使用OData(开放数据协议),一个用于查询和更新数据的协议。OData允许开发人员在URL中直接形成丰富表达的查询,带有过滤器、分页、排序和投影。例如:

1
GET /Property?$filter=ModificationTimestamp gt 2024-01-01T00:00:00Z&$orderby=ModificationTimestamp desc&$top=100

这意味着复杂的数据查询对人类可读,但与当代Web基础设施和云服务高度兼容。

与RETS通常使用基于会话的cookie相比,RESO Web API采用OAuth 2.0进行认证和授权。这种当前方法是安全的基于令牌的访问,更微服务和云原生友好。个别MLS可以使用自己的OAuth提供商或利用集中式身份系统,从而在不损害与新安全标准兼容性的情况下提供灵活性。

第二个主要进步是元数据标准化。RESO提供了一个数据字典,一个详细的规范,定义了字段名称、类型和枚举(如物业类型、状态)。也就是说,当您针对一个符合RESO的MLS构建集成时,您的代码更容易移植到其他MLS,这与RETS的碎片化世界相去甚远。

RESO还允许更高效的增量同步。开发人员可以使用ModificationTimestamp或LastUpdatedTimestamp字段仅检索更改的记录,既节省带宽又节省处理。尽管轮询仍然是一个选项,但一些MLS开始支持基于事件或推送模式,带有webhooks或流式API,允许大规模实时更新。

组件 描述
基础URL / 根端点 API访问的入口点和资源发现。
OData协议 RESTful协议,支持过滤器、排序和分页。
OAuth 2.0认证 安全的基于令牌的认证方法。
元数据($metadata) 通过OData端点暴露完整模式和数据类型。
物业资源 核心房源数据,如价格、地址、状态和媒体链接。
标准数据字典 统一的字段名称和结构,用于一致集成。
$filter 基于条件查询房源(例如,价格 > 500000)。
$select 限制返回字段以优化。
$expand 在响应中包含相关数据,如代理或办公室。
$orderby 按字段排序结果集(例如,ListPrice desc)。
$top & $skip 通过限制和偏移记录支持分页。
媒体端点 检索房源媒体(图片、平面图等)。
变更跟踪 基于时间戳仅获取新或修改的记录。
批量请求 在单个调用中进行多个查询(当支持时)。
错误处理 使用HTTP状态代码和OData错误结构。
RESO数据字典合规性 指示MLS支持的标准版本。
OpenID Connect(可选) 可选联合身份用于SSO场景。

结论

了解底层标准RETS和RESO Web API对于任何想要开发可扩展和稳定房地产系统的 solid 开发人员至关重要。尽管这些协议是为了给MLS数据带来秩序和统一性而开发的,但现实是仍然存在不一致性,可扩展性真正取决于您的系统如何接受、规范化和适应它们。

通过拥抱Go的性能和并发优势,并通过设计具有弹性和灵活性,我们已经能够构建不仅跟上MLS数据量和速度的系统,而且为未来做好准备。

在下一部分中,我们将超越定义,深入探讨技术架构、数据管道和关键实施策略,这些策略为我们的生产房源引擎提供动力。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计