首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设计AppServer访谈讨论

设计AppServer访谈讨论
EN

Stack Overflow用户
提问于 2017-12-22 17:28:53
回答 1查看 79关注 0票数 1

在最近的一次系统设计访谈中,我遇到了以下问题:

设计一个与缓存和DB接口的AppServer。

我想出了这个:

代码语言:javascript
复制
public class AppServer{
    public Database DB;
    public Cache cache;

    public Value get(Key k){
        Value res = cache.get(k);
        if(res == null){
            res = DB.get(k);
            cache.set(k, res);
        }
    }

    public void set(Key k, Value v){
        cache.set(k, v);
        DB.set(k, v);
    }
}

此代码很好,工作正常,但后续问题如下:

  1. 如果有多个线程呢?
  2. 如果有多个AppServer实例呢?
  3. 突然,AppServer性能下降了一吨,我们发现这是因为我们的缓存一直丢失。缓存大小是固定的(已经是最大的了)。我们怎样才能防止这种情况发生?

响应:

  1. 我回答说,我们可以使用锁或条件变量。在Java中,我们可以在每个方法中添加同步以允许互斥,但是面试官提到这并不是太有效,只希望关键部分同步。

我认为我们只需要同步void set(Key k, Value v)中的2条集合行和Value get(Key k)中的1条集合方法,但是面试官也要求同步res = DB.get(k);。最后我同意他的意见,但不完全理解。线程不是有独立的堆栈和共享堆吗?因此,当线程执行get时,它将res存储在堆栈帧上的局部变量中,即使另一个线程连续执行get,前一个线程也保留其get值。然后,每个线程设置各自的获取值。

  1. 我们如何处理AppServer的多个实例?

我想出了一个像Kafka这样的分布式队列解决方案,每次我们执行set / get命令时,我们都会对该命令排队,但他也提到了set是可以的,因为这个操作在缓存/ db中设置了一个值,但是如何返回get的正确值呢?有人能解释一下吗?

另外,版本控制系统和事件系统也有可能的解决方案?

  1. 可能的解决方案:
    • L1,L2,L3缓存-层和更多缓存
    • 区域/分段缓存-对用户组使用不同的缓存。
    • 还有其他想法吗?

将提出所有有洞察力的回应:)

EN

回答 1

Stack Overflow用户

发布于 2017-12-22 20:59:10

1

尽管JDBC“被认为”是线程安全的,但有些驱动程序并不是线程安全的,我将假设Cache也不是线程安全的(尽管大多数缓存应该是线程安全的),所以在这种情况下,您需要对代码进行以下更改:

  1. 使这两个字段都成为最终结果
  2. 同步整个get(...)方法
  3. 同步整个set(...)方法

假设没有其他方法访问上述字段,那么get(...)方法的行为取决于两件事:首先,可以看到来自set(...)方法的更新,其次,缓存丢失仅由单个线程存储。您需要同步,因为在缓存丢失的情况下,只有一个线程执行昂贵的DB查询。如果不同步整个get(...)方法,或者拆分同步语句,则另一个线程也可能在查找和插入之间看到缓存丢失。

我回答这个问题的方式是诚实地抛出整个问题。我会看看JCIP是如何编写缓存的,并以此为基础给出答案。

2

我认为你的队列解决方案很好。

我相信您的面试官的意思是,如果AppServer的另一个实例没有缓存已经是set(...)的内容,那么它将在DB中查找并找到正确的值。如果您使用多个线程,则此解决方案将是不正确的,因为两个线程可能存在冲突的值,那么缓存将有两个不同的值,而取决于您的DB的线程安全性,它甚至可能根本没有值。

理想情况下,您不会创建多个AppServer实例。

3.

我没有足够的经验来具体地评估这个问题,但是也许LRU缓存会在一定程度上提高性能,或者使用哈希环缓冲区。这可能有点牵强,但如果您想抛出它,甚至可以使用ML来确定最佳值,例如,在一天中的特定时间预加载以保留的值也可能有效。

如果缓存中总是缺少值,则无法改进代码。性能将取决于您的数据库。

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

https://stackoverflow.com/questions/47945244

复制
相关文章

相似问题

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