Apache License 2.0

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

深度技术分析:Ecto 3 适配 ETS 表的 etso 项目

项目背景与痛点

在 Elixir 生态系统中,Ecto 是一种流行的数据库交互库,广泛应用于 Elixir Web 开发。然而,Ecto 通常依赖关系数据库进行持久化存储,这并不总是理想的解决方案。尤其是对于需要极快响应时间和内存内数据存储的场景,比如实时缓存或会话管理,关系数据库显得力不从心。为了更好地满足这种需求,evadne/etso 项目引入了 ETS(Erlang Term Storage)表作为 Ecto 模式的数据存储方案。这不仅提高了数据访问速度,同时也保持了与 Ecto 3 的兼容性,从而为开发者提供了一种更具灵活性和高性能的选择。

核心技术揭秘

evadne/etso 项目的本质在于将 Ecto 模式映射到内存中的 ETS 表,并提供了一套兼容 Ecto 会话接口的实现。整个框架通过巧妙地应用 Elixir 的抽象能力,以尽可能透明的方式将 Ecto 模式背后的 ETS 存储逻辑隐藏了起来。这样的设计不仅使得原有 Ecto 的查询和更改接口可以有效兼容 ETS,且在性能上有了显著的提高。

graph TD A[用户请求] --> B{"验证模式"} B -->|"是 Ecto 模式"| C[调用 ETS 管理器] C --> D[读取/写入 ETS] C -->|"异常处理"| F[错误处理] B -->|"不是 Ecto 模式"| E[走传统 Ecto 流程] E --> G[数据库持久化]

架构与实现

evadne/etso 项目的实现基于 Elixir 的元编程以及 ETS 数据结构。模块的核心在于一个自定义的 Ecto 适配器,它能够动态解析并处理 Ecto 模型,将此类模型的行为导入内存中的 ETS 表。当请求进入系统时,首先通过适配器进行模型验证,若该模型属于 Ecto 模式,则直接委托给 ETS 管理器进行读写操作。Ecto 的事务机制被重写以适应 ETS 的原生操作,保持功能的无缝衔接。

功能亮点与差异

与传统的基于关系数据库的 Ecto 适配器相比,evadne/etso 最突出的优势在于其显著提升了数据访问速度,特别是在读取密集的场景中。此外,内存内的 ETS 表为开发者提供了即时的数据操作能力,减少了 I/O 存在的瓶颈,进一步增强了系统的响应速度。更为重要的是,evadne/etso 采用了相同的 Ecto 查询接口,使得迁移成本较低,对于希望保留原有逻辑结构并快速采纳内存存储优化的开发者来说,这无疑是一个巨大的诱惑。

应用场景与落地建议

在生产环境中运用 evadne/etso,需要注意内存管理的问题,尤其是数据量较大或存在大量并发读写的场景中,内存的瓶颈、数据一致性和事务管理都是需要精心考虑的关键点。evadne/etso 非常适合以下场景:

  1. 高频读取、低频写入的缓存或代理服务。
  2. 短暂会话管理,如在线游戏状态储存。
  3. 任何需要大量数据在内存中进行实时处理的应用。

部署时,应根据实际业务需求调整 ETS 表的大小以及内存配额,同时,合理的设计事务管理机制,保证系统在高并发情况下的数据一致性。

综合评价

evadne/etso 项目在性能优化上具有显著优势,通过 ETS 提供了超快的数据读写能力,且与 Ecto 3 的原生兼容性让用户可以无缝迁移。但其也存在固有的缺点,如内存管理、数据持久性的问题需要开发者额外处理,以及在数据量较大的情况下,会受制于内存限制。不过,对于希望在内存内存储并处理数据的场景,evadne/etso 无疑是当前 Elixir 生态系统中的一个极佳选择。

关于

GitHub 原始描述(英文)

Ecto 3 adapter allowing use of Ecto schemas held in ETS tables

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
473
价值分
244
活跃状态
活跃

语言占比

Elixir

README

Etso

Etso is an ETS adapter, allowing you to use Ecto schemas with ETS tables.

Within this library, a bare-bones Ecto Adapter is provided. The Adapter transparently spins up ETS tables for each Ecto Repo and Schema combination. The tables are publicly accessible to enable concurrency, and tracked by reference to ensure encapsulation. Each ETS table is spun up by a dedicated Table Server under a shared Dynamic Supervisor.

For a detailed look as to what is available, check out Northwind Repo Test.

Highlights & Benefits

Key highlights of this library are:

  • It transparently handles translations between Ecto.Schema structs and ETS tuples.
  • It knows how to form ETS Match Specifications for simple queries.

Key points to consider when adopting this library are:

  • It is suitable for rapid retrieval of simply formatted data, for example presets that do not change frequently.
  • It is not suitable for use as a full-fledged data layer unless your requirements are simple.

Feature Coverage

The following features are working:

  • Basic query scenarios (C / R / U / D)
    • Insert all (c:Ecto.Repo.insert_all/3, etc.)
    • Insert one (c:Ecto.Repo.insert/2, etc.)
    • Get all (c:Ecto.Repo.all/2, etc.)
    • Get by ID (c:Ecto.Repo.get/3, etc.)
    • Get where (Ecto.Query.where/3, etc.)
    • Delete by ID (c:Ecto.Repo.delete/2, etc.)
  • Selects
  • Assocs
  • Preloads

The Northwind Repo Test should give you a good idea of what’s included.

Missing Features

The following features, for example, are missing:

  • Composite primary keys
  • Dynamic Repos (c:Ecto.Repo.put_dynamic_repo/1)
  • Aggregates (dynamic / static)
  • Joins
  • Windows
  • Transactions
  • Migrations
  • Locking

Installation

Using Etso is a two-step process. First, include it in your application’s dependencies:

defp deps do
  [
    {:etso, "~> 1.1.0"}
  ]
end

Afterwards, create a new Ecto.Repo, which uses Etso.Adapter:

defmodule MyApp.Repo do
  @otp_app Mix.Project.config()[:app]
  use Ecto.Repo, otp_app: @otp_app, adapter: Etso.Adapter
end

Once this is done, you can use any Schema against the Repo normally, as you would with any other Repo. Check out the Northwind modules for an example.

Utilisation

Originally, Etso was created to answer the question of whether ETS and Ecto can be married together. It has since found some uses in production applications, serving as a Data Repository for pre-defined nested content. This proved invaluable for rapid iteration.

If you have other Use Cases for this library, please add it here with a Pull Request.

  • The Erlef Website is using Etso to cache and query news and event posts that are parsed and imported into the Repo on application startup.

Further Note

This repository is extracted from a prior project ETS Playground, which was created to support a session at ElixirConf EU 2019, Leveraging ETS Effectively.

Specifically, this library was created to illustrate the point that ETS can serve as a scalable storage layer for data which changes infrequently. Check out the Northwind Importer for an example.

Acknowledgements

This project contains a copy of data obtained from the Northwind database, which is owned by Microsoft. It is included for demonstration and testing purposes only, and is excluded from the distribution. The Author thanks Microsoft Corporation for the inspiration.

The Author also wishes to thank the following individuals:

评论

暂无评论