代码之家  ›  专栏  ›  技术社区  ›  taleinat

如何使python对象在Web应用程序中持久化?

  •  6
  • taleinat  · 技术社区  · 17 年前

    我正在编写一个相当复杂的Web应用程序。python后端运行的算法的状态取决于存储在几个不经常更改的相互关联数据库表中的数据,以及经常更改的特定于用户的数据。当用户使用应用程序时,算法的每用户状态会经历许多小的变化。这个算法经常在每个用户的工作中用来做一些重要的决定。

    出于性能原因,对来自(半规范化)数据库数据的每个请求重新初始化状态很快变得不可行。例如,最好以某种方式缓存状态的python对象,以便在必要时使用和/或更新它。但是,由于这是一个Web应用程序,因此有几个进程为请求提供服务,因此使用全局变量是不可能的。

    我已经尝试序列化相关对象(通过pickle)并将序列化数据保存到数据库,现在正在尝试通过memcached缓存序列化数据。但是,这仍然有大量的开销,经常对对象进行序列化和反序列化。

    我看过共享内存解决方案,但唯一相关的是 POSH . 然而,posh似乎并没有被广泛使用,我觉得将这样一个实验组件集成到我的应用程序中并不容易。

    我需要一些建议!这是我第一次尝试开发一个Web应用程序,所以我希望这是一个足够普遍的问题,这样的问题有众所周知的解决方案。此时,假设Python后端在单个服务器上运行的解决方案就足够了,但对于扩展到多个服务器的解决方案,还需要额外的要点:)

    笔记:

    • 我有这个应用程序在工作,目前正在使用,并且有活跃的用户。我开始时没有做任何过早的优化,然后根据需要进行优化。我已经进行了测量和测试,以确保上述问题是实际的瓶颈。我确信我可以从当前的设置中获得更多的性能,但我想问一下是否有更好的方法。
    • 安装本身仍在进行中;假设系统的体系结构可以是解决方案的任何套件。
    6 回复  |  直到 17 年前
        1
  •  3
  •   Rafał Dowgird    17 年前

    我认为 multiprocessing 框架具有这里可能适用的内容——即共享CTypes模块。

    多处理对于Python来说是相当新的,所以它可能有一些奇怪之处。我不太确定解决方案是否适用于不是通过 multiprocessing .

        2
  •  8
  •   S.Lott    17 年前

    注意提前优化。

    另外:“python后端运行的算法的状态…”是Web框架中的会话。就是这样。让django框架在缓存中维护会话状态。时期。

    “当用户使用应用程序时,算法的每用户状态会经历许多小的变化。”大多数Web框架都提供一个缓存会话对象。通常它的性能非常高。见Django session documentation 为此。

    忠告。[修订]

    看来你有什么有用的东西。利用它来学习你的框架,学习工具,学习你可以转动哪些旋钮而不必费力。具体来说,使用会话状态。

    第二,玩弄缓存、会话管理和容易调整的东西,看看你是否有足够的速度。通过尝试,了解MySQL套接字或命名管道是否更快。这些是非编程优化。

    第三,测量性能以找到实际的瓶颈。准备好以足够细的粒度提供(并保护)测量结果,使其足够有用和稳定,以便对备选方案进行有意义的比较。

    例如,显示持久会话和缓存会话之间的性能差异。

        3
  •  2
  •   JV.    17 年前

    我想你可以给佐布一个机会。

    “ZODB的一个主要特点是透明度。您不需要编写任何代码来显式地将对象读写到数据库或从数据库中读写。您只需将持久性对象放入一个容器中,该容器的工作方式与Python字典类似。字典中的所有内容都保存在数据库中。这本词典被称为数据库的“根”。它就像一个魔术包,任何放在里面的Python对象都会变得持久。”

    最初它是Zope的一个组成部分,但最近也有一个独立的包可用。

    它有以下限制:

    “实际上,对于可以存储在zodb中的内容有一些限制。您可以将任何可以“pickle”的对象存储为标准的跨平台串行格式。列表、字典和数字等对象可以被pickle处理。文件、套接字和python代码对象等对象不能存储在数据库中,因为它们不能被pickle。”

    我读过,但我自己也没试过。

    另一个可能的事情是内存中的sqlite-db,这可能会加快进程一点——成为内存中的db,但仍然需要做序列化的工作。 注意:内存中的数据库在资源上很昂贵。

    这里有一个链接: http://www.zope.org/Documentation/Articles/ZODB1

        4
  •  2
  •   M. Utku ALTINKAYA    17 年前

    首先,您的方法不是常见的Web开发实践。即使使用了多线程,Web应用程序也被设计成能够运行多处理环境,以实现可扩展性和更容易的部署。

    如果您只需要初始化一个大对象,以后不需要更改,您可以通过使用一个在创建WSGi应用程序时初始化的全局变量,或者模块包含正在加载的对象等,轻松地完成初始化,多处理将为您做得很好。

    如果需要更改对象并从每个线程访问它,需要确保对象是线程安全的,请使用锁来确保。并使用一个服务器上下文,一个进程。任何多线程的python服务器都能很好地为您服务,而且对于这种设计,fcgi也是一个很好的选择。

    但是,如果多个线程正在访问和更改您的对象,那么锁可能会对您的性能提高产生非常坏的影响,这可能会使所有的好处都消失。

        5
  •  2
  •   saffsd    17 年前

    这是Durus,一个用于用Python编写的应用程序的持久对象系统。 程序设计语言。Durus提供了一种使用和维护一致性的简单方法 一个或多个进程使用的对象实例集合。A的访问和更改 持久实例通过缓存的连接实例进行管理,其中包括 commit()和abort()方法,使更改具有事务性。

    http://www.mems-exchange.org/software/durus/

    我以前在一些研究代码中使用过它,在那里我希望持久保存某些计算的结果。我最终转向了 pytables 因为它更好地满足了我的需要。

        6
  •  1
  •   Andrew Cox    17 年前

    另一种选择是检查状态的需求,听起来如果序列化是瓶颈,那么对象就非常大。你真的需要这么大的东西吗?

    我知道在StackOverflowPodcast27中,Reddit的人讨论他们使用什么作为状态,这样可能有助于倾听。