65.9K
CodeProject 正在变化。 阅读更多。
Home

可扩展的对象持久化 (SOP)

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2024年1月25日

MIT

5分钟阅读

viewsIcon

2761

可扩展对象持久化,ACID事务适配器

引言

对象持久化和ACID事务是软件开发中备受追捧的两个要素。尽管存在关系型数据库和SQL,架构师和开发人员仍然倾向于基于面向对象范例设计解决方案。ACID事务仍然被高度渴求。

我们有ORM,即对象关系映射器,例如Java中的JPA和.NET中的Entity Framework。但这些解决方案提供的是“映射”,而不是实际对象的持久化。该解决方案强制执行“映射”和SQL中间件的开销。当您构建高性能和高并发系统时,这种开销会变得显著且明显,其中对跨机器的并发/并行进行细粒度控制,通过“对齐”数据持久化,即高效的分布式处理,将带来好处。

对象持久化(通过SOP)通过移除映射和SQL中间件层来解决这个问题,并提供最佳的ACID事务和内置缓存等功能。

背景

SOP的起源在.NET。第一次尝试取得了一定的成功,但由于功能的不断叠加导致组件变得复杂且难以推进,因此从未投入生产。它是这个新概念的原型。

因此,它被重新设计,权衡了功能与进度,在设计模式(例如存储库模式)的采纳上采取了更好的立场,并将其移植到了Golang。当前版本V2是Golang端口,并实现了广告中所述的目标。

Using the Code

SOP具有B-Tree接口(CRUD方法)和用于管理事务会话的事务API。

示例代码如下

import (
    "github.com/SharedCode/sop/in_red_ck"
    "github.com/SharedCode/sop/in_red_ck/cassandra"
    "github.com/SharedCode/sop/in_red_ck/redis"
)

// Cassandra cluster config.
var cassConfig = cassandra.Config{
    ClusterHosts: []string{"localhost:9042"},
    Keyspace:     "btree",
}
// Redis config.
var redisConfig = redis.Options{
    Address:                  "localhost:6379",
    Password:                 "", // no password set
    DB:                       0,  // use default DB
    DefaultDurationInSeconds: 24 * 60 * 60,
}

// Initialize Cassandra & Redis.
func init() {
    in_red_ck.Initialize(cassConfig, redisConfig)
}

var ctx = context.Background()
...

func main() {
    // Create a transaction session & begin it.
    trans, _ := in_red_ck.NewTransaction(true, -1)
    trans.Begin()

    // Create/instantiate a new B-Tree named "fooStore" w/ 500 slots & other parameters
    // including the "transaction" that it will participate in.
    //
    // Key is of type "int" & Value is of type "string".
    b3, _ := in_red_ck.NewBtree[int, string]
             (ctx, "fooStore", 500, false, false, true, "", trans)

    // Add an item with key 1 and value "hello world".
    b3.Add(ctx, 1, "hello world")

    ...

    // Once you are done with the management, 
    // call transaction commit to finalize changes, save to backend.
    trans.Commit(ctx)
}

另外一个示例说明将对象作为键值对进行管理

// Sample Key struct.
type PersonKey struct {
    Firstname string
    Lastname  string
}

// Sample Value struct.
type Person struct {
    Gender string
    Email  string
    Phone  string
    SSN    string
}

// Helper function to create Key & Value pair.
func newPerson(fname string, lname string, gender string, 
               email string, phone string, ssn string) (PersonKey, Person) {
    return PersonKey{fname, lname}, Person{gender, email, phone, ssn}
}

// The Comparer function that defines sort order.
func (x PersonKey) Compare(other interface{}) int {
    y := other.(PersonKey)

    // Sort by Lastname followed by Firstname.
    i := cmp.Compare[string](x.Lastname, y.Lastname)
    if i != 0 {
        return i
    }
    return cmp.Compare[string](x.Firstname, y.Firstname)
}

func main() {

    // Create and start a transaction session.
    trans, err := in_red_ck.NewTransaction(true, -1)
    trans.Begin()

    // Create the B-Tree (store) instance.
    b3, err := in_red_ck.NewBtree[PersonKey, Person]
               (ctx, "persondb", 500, false, false, false, "", trans)

    // Add a person record w/ details.
    pk, p := newPerson("joe", "krueger", "male", "email", "phone", "mySSN123")
    b3.Add(ctx, pk, p)

    ...
    // To illustrate the Find & Get Value methods.
    if ok, _ := b3.FindOne(ctx, pk, false); ok {
        v, _ := b3.GetCurrentValue(ctx)
        // Do whatever with the fetched value, "v".
        ...
    }

    // And lastly, to commit the changes done within the transaction.
    trans.Commit(ctx)
}

方法是完整的,您可以执行基本的CRUD操作(例如,如上所示的添加,更新移除获取当前值获取当前键获取当前项),以及一些支持范围查询和范围更新的功能,例如

  • FindOne - 根据键搜索项目
  • Next - 相对于当前“光标”位置导航到下一个键
  • Previous - 相对于当前“光标”位置导航到上一个键
  • First - 根据键排序序列移动到第一个记录
  • Last - 根据键排序序列移动到最后一个记录

您可以在一个事务中管理多个B-Tree存储,并在不同时间或并发地管理多个事务。

此处摘录了SOP的Wiki,以便从高层次上提供详细描述

SOP V2是一个Golang代码库,提供可扩展对象持久化。它是一个通用数据库引擎,具有ACID事务和两阶段提交,可无缝集成到第三方数据库。

使用SOP,您只需定义应用程序数据(struct),SOP将负责存储和检索。它提供基于事务的API,赋予您事务的ACID属性。

SOP能够结合Cassandra(这样我们就无需重新发明轮子)和Redis的全局缓存的最佳特性,并在此基础上增加ACID事务和基于对象的*数据管理。您不再需要在Cassandra中编写表(以及SQL脚本/ORM),因为SOP负责对象持久化和非常快速的搜索(使用M-Way Trie B-Tree)到Cassandra。此外,您也不再需要编写基于Redis的数据缓存,因为SOP已内置了该功能。

由于SOP将您的应用程序(微服务、Web服务器等)变成了数据库服务器本身,我们基本上消除了设置中的繁重的SQL中间件。从而,为您的应用程序提供了后端存储引擎的原始强大功能。

并且,通过使用像Golang这样酷的语言,您的数据挖掘逻辑突然与您的应用程序完全一致。不再有阻抗失配。

使用Redis以非常高效的方式实现了创建或支持ACID事务所需的所有组件或要素。例如,没有行锁定,而是通过使用基于Redis的算法来实现等效的锁定,用于面向批处理的逻辑锁定。

SOP能够提供通用的、领域“灵活”的数据管理解决方案,该方案将始终可扩展,因为M-Way Trie已成为对象“容器”(SOP称之为“存储”,但类似于关系型数据库中的表或一组表)的商品(或核心功能)。在一种情况下,它可以是您的薪资和库存数据库系统;在另一种情况下,它可以是您的AI数据库,用于存储“向量”等。

SOP作为一个框架,非常便携且高度适应。在V2中,它结合了Cassandra和Redis并增强了解决方案,添加了上述很酷的功能。它还附带一个“内存”版本,可以用作有序映射。

未来版本可以集成到其他存储子系统等,或者,如果需要并且有要求,甚至拥有自己的存储功能。

这是GitHub上项目的链接:https://github.com/SharedCode/sop,用于获取完整源代码。

如果您对此感兴趣或好奇,并且可能渴望加入其中。我热忱地邀请您。该项目是一个初创项目,需要整个技术栈的优秀人才——从经理、主管、架构师、开发人员、QA、文档编写人员等。

代码是可靠的,并已通过大量的自动化测试,但这个概念是新的,这是第一次发布或讨论。因此,到目前为止,我只有我一个人是贡献者。

无论如何,我希望您在了解这个概念的过程中感到愉快,并对这个方向产生了兴趣。我相信这个项目和当前的实现可以真正帮助加速和简化应用程序开发,为低延迟、“横向”因此高度可扩展的系统提供简单的解决方案。

关注点

显然(“设想”并在实现中得到证明!),M-Way Trie(B-Tree)数据结构和算法是启用ACID事务的绝佳“伴侣”功能。ACID事务是一个易于在“控制器”中实现的功能,而像B-Tree这样的存储算法在其在存储流程中的位置方面天然就是“控制器”。

如果缓存作为解决方案的内置部分(在这个SOP设置中),将消除创建可扩展系统所需的许多编码工作,因为缓存是内置的。

最后,使用基于对象的数据库引擎可以简化应用程序开发,使其比以往任何时候都更有趣(也更简单)。

历史

  • 2024年1月24日:当前版本 - SOP V2 Golang
© . All rights reserved.