首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >高度分布式OLTP架构

高度分布式OLTP架构
EN

Stack Overflow用户
提问于 2016-06-05 12:21:21
回答 3查看 254关注 0票数 1

有没有一种已知的架构解决方案,适用于适用前提条件的高度分布式OLTP情况?例如,让我们使用一个银行示例。个人A想要将$N转给个人B。成功的前提条件是个人A的帐户中必须有超过$N的帐户。

从人员A的角度来看,他们登录到某个web应用程序。他们为$N创建了从自己到个人B的转账。请记住,在后台,在申请此转账和创建转账时,会实时从个人A的账户中提取和存入资金。钱可能在创建之前就存在了,但一旦应用了转移,它可能就不存在了。换句话说,这不可能是客户端验证。个人A想知道此转接是否同步成功或失败。个人A不希望异步提交传输,然后稍后返回到队列或某个传输已失败的通知。

有没有一种已知的架构可以大规模解决这个问题?如果所有帐户都在单个RDBMS中,那么您可以通过内置的事务功能执行类似的操作。但是如果你使用的是一个最终一致的NoSQL风格的数据存储,或者像Kafka这样的基于日志/消息的基础设施,那么有没有解决此类问题的已知解决方案呢?

EN

回答 3

Stack Overflow用户

发布于 2016-06-08 15:47:52

基本上,您需要的是分布式锁定机制。许多分布式服务器应用程序都提供了这样的功能。

基本上,如果我们将您的问题转换为代码,它将如下所示

代码语言:javascript
复制
// BANK WITHDRAWAL APPLICATION

// Fetch BankAccount object from NCache
BankAccount account = cache.Get("Key") as BankAccount; // balance = 30,000
Money withdrawAmount = 15000;

if (account != null && account.IsActive)
{
    // Withdraw money and reduce the balance
    account.Balance -= withdrawAmount;

    // Update cache with new balance = 15,000
    cache.Insert("Key", account);
}

=========================

代码语言:javascript
复制
// BANK DEPOSIT APPLICATION

// Fetch BankAccount object from NCache
BankAccount account = cache.Get("Key") as BankAccount; // balance = 30,000
Money depositAmount = 5000;

if (account != null && account.IsActive)
{
    // Deposit money and increment the balance
    account.Balance += depositAmount;

    // Update cache with new balance = 35,000
    cache.Insert("Key", account); 
}

这基本上是一个竞态条件的例子。

竞争条件是指两个或更多用户试图同时访问和更改相同的共享数据,但最终以错误的顺序进行。

上述代码在分布式锁定中的答案是

代码语言:javascript
复制
LockHandle lockHandle = new LockHandle();

// Specify time span of 10 sec for which the item remains locked
// NCache will auto release the lock after 10 seconds.
TimeSpan lockSpan = new TimeSpan(0, 0, 10); 

try
{
    // If item fetch is successful, lockHandle object will be populated
    // The lockHandle object will be used to unlock the cache item
    // acquireLock should be true if you want to acquire to the lock.
    // If item does not exists, account will be null
    BankAccount account = cache.Get(key, lockSpan, 
    ref lockHandle, acquireLock) as BankAccount;
    // Lock acquired otherwise it will throw LockingException exception

    if(account != null && account.IsActive)
    {
        // Withdraw money or Deposit
        account.Balance += withdrawAmount;
        // account.Balance -= depositAmount;

        // Insert the data in the cache and release the lock simultaneously 
        // LockHandle initially used to lock the item must be provided
        // releaseLock should be true to release the lock, otherwise false
        cache.Insert("Key", account, lockHandle, releaseLock); 
    }
    else
    {
        // Either does not exist or unable to cast
        // Explicitly release the lock in case of errors
        cache.Unlock("Key", lockHandle);
    } 
}
catch(LockingException lockException)
{
    // Lock couldn't be acquired
    // Wait and try again
}

这个答案对于NCache (一个分布式缓存)来说是非常具体的。我相信你会在关键字‘分布式锁定’下找到更多的解决方案。

Source

票数 0
EN

Stack Overflow用户

发布于 2016-12-21 02:52:24

你看过Splice Machine吗?它是一个完全兼容ACID的RDBMS,运行在hadoop堆栈(hbase、spark、hdfs、zookeeper)之上。它们具有双重架构,使用hbase进行快速OLTP查询,并使用spark进行OLAP查询,并且内置了不需要任何锁定的事务功能。

票数 0
EN

Stack Overflow用户

发布于 2019-03-20 06:26:07

ClustrixDB是另一个值得一试的解决方案。它使用Paxos进行分布式事务解析(内置于符合ACID、SQL的分布式RDBMS中),并具有内置的容错功能。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37638419

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档