【问题标题】:Best Solution for Caching缓存的最佳解决方案
【发布时间】:2010-11-05 04:19:50
【问题描述】:

在基于 Web 的应用程序中实现缓存的最佳位置在哪里?

  • 在表示层(希望不是)?
  • 在业务逻辑层?
  • 在数据层?

我将在后台使用 memcached 或 MS Velocity 之类的东西。

我只是发现自己编写了这么多代码来更新业务逻辑层中的缓存,那么在数据库服务器的数据访问层之间创建一个结构来缓存数据会更好吗?

我认为这些复杂性归结为一个事实,我们缓存的大部分数据都是特定于用户的,并且我们在缓存中复制数据。我们努力寻找最佳解决方案。

【问题讨论】:

    标签: asp.net-mvc caching memcached


    【解决方案1】:

    缓存:在数据访问层实现,由业务逻辑层访问

    这意味着您必须小心缓存是否过时。

    【讨论】:

      【解决方案2】:

      数据层 - 该层之上的所有层都不需要知道数据的来源。我也只会缓存不是很不稳定的数据,或者包含一些过期策略。

      【讨论】:

        【解决方案3】:

        我们在与表示层交互之间的业务逻辑层实现它。如果来自表示层的请求进入并被缓存,我们就可以跳过大量的逻辑和数据访问。

        我强烈推荐 MemCached 而不是 MS Velocity,Velocity 设置起来很痛苦!

        【讨论】:

          【解决方案4】:

          数据层。但它令人困惑,因为我们使用 ASP.NET 缓存。凭借其过期和依赖功能,它非常方便。所以我们的业务层不知道数据层可能正在缓存,但数据层使用表示层技术进行缓存! :(

          【讨论】:

          • ASP.NET 缓存的问题在于它不是分布式或跨应用程序和应用程序域共享的,MemCached 和 Velocity 允许这样做,这就是我们切换到它的原因。
          • 非常正确。我用 SqlCacheDependency 玩游戏,但成功有限。我很想和MC或V一起去。
          【解决方案5】:

          如果您正在缓存业务对象,并且考虑到您描述的正在使用的 3 层,那么业务层是显而易见的地方。

          一个简单的设置是(对于单个业务对象):

          1. MyCache 是一个静态类
          2. 一个静态方法:MyCache.Retrieve(id),返回一个对象
          3. 该类使用静态Dictionary 进行存储,使用静态ReaderWriterLock

          Retrieve 方法然后执行以下操作:

          1. id 是否在缓存中(id/object 的Dictionary)?
          2. 没有
            • 从数据库中获取对象
            • AquireWriterLock 来自 ReaderWriterLock(为什么选择 ReaderWriter?因为你不经常写作,但你经常阅读)
            • 将对象添加到缓存中
          3. 是的
            • 从字典中检索对象

          这是我的首选解决方案,您可以根据需要添加超时、清除等。或者使用 memcached 或 Microsoft Enterprise Library Caching Block,但它们通常是矫枉过正的。

          【讨论】:

            【解决方案6】:

            我不能说 ASP.NET 特定的东西,但我通常发现您可以在每个级别进行缓存。您的数据层将缓存数据响应,您的表示层可能需要缓存生成的表示元素(例如,用户特定的样式表)等。在大多数情况下,数据层是最重的缓存用户,其他层将包括如果证明有必要,则提供对象缓存。

            最难的部分是让缓存失效正常工作。陈旧的缓存是部署期间的一个主要问题。确保弄清楚您将如何管理每个缓存对象的生命周期。 LRU 缓存适用于根据需求缓存静态元素。然而,大多数数据缓存都需要一个明确的生命周期,无论它是基于过期计时器还是与某种用户会话相关联。

            【讨论】:

              【解决方案7】:

              缓存是一种性能优化,所以要在瓶颈所在的地方做。您可以通过测量三次然后再测量一次来知道瓶颈在哪里。

              请注意缓存时数据的松散一致性,例如您不想缓存所有股票交易应用程序。

              【讨论】:

                【解决方案8】:

                您应该考虑在每一层进行缓存。

                缓存的最佳位置是尽可能靠近客户端请求(因此您可以尽可能少地为响应提供服务)。在 Web 应用程序中,是的,在表示层、业务层和数据层。

                (旁注:如果您基本上是在您的业务逻辑代码中到处使用缓存逻辑,那么您真的应该查看seperation of concerns 以避免您的代码变成一团泥浆:-))

                【讨论】:

                  【解决方案9】:

                  缓存是一个重要的部分或网络应用程序,但没有适合每个项目的神奇解决方案。在您的应用程序运行之前进行优化通常是一个坏主意。在问自己应该在哪里实现缓存层之前,第一步是确保您的应用程序在没有任何缓存优化的情况下运行良好(即使速度很慢)。

                  完成第一步后,您可以开始分析应用程序,列出似乎使用大量资源(可能是 CPU、内存、I/O、数据库访问)或花费大量时间的功能完成(通常是因为相同的症状)。

                  一旦您列出了您认为可以使用缓存系统优化的功能,您需要问自己两个问题:

                  • “如何同时改进所有这些功能”(宏观焦点):对此问题的一个明显答案通常是数据访问缓存。如果返回的数据始终相同,您通常不希望一遍又一遍地向数据库服务器发送相同的查询。因此,将这种类型的数据存储在缓存中,并具有巧妙的生命周期,将始终是一个好主意。

                  • “如何改进每个功能”(微焦点):这很棘手,您需要非常了解您的应用程序才能弄清楚这一点。有些数据可以缓存,有些不应该,有些不能。调试器和分析器通常是执行此步骤的绝佳工具,因为它们可以帮助您确定某项功能缓慢的原因,并为您提供有关如何优化它们的提示。

                  您要进行的优化可能与应用程序的任何层(表示、业务逻辑、数据)相关,但这并不意味着您应该全部实施。您应该考虑几件重要的事情:

                  • 这个特性真的需要优化吗? (这对客户来说是否有明显的收益?对于硬件?对于整个应用程序?对于其他应用程序?)
                  • 我可以获得哪些性能提升? (1%、200%、...)
                  • 优化它需要多长时间? (1 小时,12 天,...)
                  • 优化它的风险有多大? (它会对应用造成破坏吗?对于客户而言?)

                  一旦您获得了这些问题的答案,就该与您的项目经理、您的同事,甚至是不与您一起处理应用程序的人讨论这个问题。有中立的意见是好的,以及有非技术性(或技术性较低)的意见。与这些人交谈应该可以帮助您弄清楚应该做什么和不应该做什么。

                  此时,您应该有一个非常清晰的优化列表,经过多次思考,编码和测试它们应该没有问题。

                  【讨论】:

                  • 我同意缓存需要很好地理解您的应用程序。但我认为我们不应该在完成您提到的第一步应用程序后开始编写缓存解决方案。但我们应该早点计划。由于需要缓存的主要部分从一开始就很明显,但后来您可能会发现更多需要注意的部分。例如,字典和查找是缓存世界中的第一个公民,因此您应该从一开始就做好计划。如果你把它推迟到最后,你将需要修改所有触及这部分的地方。
                  猜你喜欢
                  • 1970-01-01
                  • 2011-03-01
                  • 2019-10-14
                  • 1970-01-01
                  • 2020-04-12
                  • 1970-01-01
                  • 2023-03-13
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多