6

我正在考虑使用与 memcached 配对的 noSQL (mongoDB) 在我的 web 应用程序中存储会话。这个想法是,在每次页面加载时,将用户数据与 memcache 中的数据进行比较,如果发生变化,数据将同时写入 memcached 和 mySQL。这样,读取将大大减少,并利用 memcached 来做它最擅长的事情。

但是,我有点担心使用非 ACID 数据库进行会话存储,尤其是使用 memcached 层。假设在将会话更新到数据库时出现问题,我们的用户立即感到头疼,想知道为什么他们放入购物车的产品没有出现......

对此有什么合适的方法?我们应该使用 mySQL 会话存储还是为会话保留一个非酸性支持数据库是否可以?

谢谢!

4

6 回答 6

4

我目前使用 MongoDB 作为会话存储。可以避免 pilif 提到的竞争条件。我找到了一个实现 MongoDB 会话处理程序的类 ( http://www.jqueryin.com/projects/mongo-session/ ) 并将它分叉在 github 上以满足我的需要 ( http://github.com/halfdan/MongoSession)。

于 2010-09-14T09:49:23.877 回答
1

如果没有对会话进行任何锁定,请非常非常小心您存储的内容。永远不要存储任何依赖于你之前读过的东西,因为数据可能会在你读和写之间发生变化——尤其是在 ajax 的情况下,多个请求可以同时发出。

一个你不能在非锁定会话中存储的例子是购物车,因为要添加产品,你必须阅读、反序列化、添加产品然后再次序列化。如果任何其他请求在第一个请求读取和写入之间执行相同的操作,您将丢失第二个请求的数据。

详细查看这篇文章:http: //thwartedefforts.org/2006/11/11/race-conditions-with-ajax-and-php-sessions/

将会话保留在您的文件系统(PHP 为您锁定它们)、数据库(您必须手动锁定)中,或者永远不要向您的会话写入任何有价值的值,如果该值来自先前的读取。

于 2010-09-10T15:58:46.410 回答
1

如果您不想丢失数据,请坚持使用 ACID 测试数据库。

你在寻找什么回报?

如果你想要一个安全的系统,你不能信任用户的任何东西,除了可能选择的整数,所以让他们存储信息通常是一个非常糟糕的主意。

我看不到将会话存储在 MySQL 数据库之外的回报。如果您担心的话,您可以对表进行 cron 清理,但为什么要麻烦呢?一些用户会在网站上购物,然后暂时分心。然后他们会在一两天后回来。

如果您使用 cookie 或其他真正临时的东西来存储他们的会话信息,那么他们的购物时间很有可能被浪费了。用户真的很珍惜他们的时间......所以如果你将他们的会话信息存储在数据库中,你可以编写一些性感的东西来管理这些数据。

另外,这样做的好处是,您将生成大量关于人们喜欢您网站上的内容的残留信息,这些信息可能以后无法提供给您。就像您甚至可以将其中的一些视为民意调查或人们添加到购物车中的物品可能会影响您管理业务、订购库存或集中营销的方式。

如果您选择真正临时的东西,那么您将失去获得剩余收益的机会。

于 2010-09-15T14:01:27.833 回答
1

我会看看用户获得多少成本,然后询问实施一个真正好的系统的成本是多少。请记住,用户是一种生物重试方法。“我很无聊......再次按下重新加载......”虽然这不是最完美的解决方案,但有时它与“不丢失任何东西 - 永远”的成本比较是可以接受的。

如果您想要额外的安全性,您可以将您的会话缓存到一组单独的内存缓存服务器,这样就不会出现意外刷新。:)

还有许多其他系统 membase.org,以及一些其他持久性 memcache 解决方案(java 实现),它们会将存储持久化到磁盘。如果您想稍微修改您的客户端,或者您如何访问 memcache,您可以自己复制 memcache 会话对象。

-丹尼尔

于 2010-09-16T22:43:19.380 回答
1

If you write your app so that the user stores all session information client side, then you just verify that information as needed, you won't need to worry about sessions on the server side. This is one of the principles in REST style architecture. For instance, if the user is requesting adding an item to their shopping cart, just store the itemID list and count on the client side. When you hit the cart page, you can easily look up the item information from the list of itemIDs they are telling you are in their cart.

During checkout, go directly against the database with transactions to ensure you aren't getting any race conditions, and check your live inventory. If inventory isn't there when they go to check out, just say, "sorry, we just sold out". Of course, at that point you should go update any caches you have out there that are telling people you have inventory.

于 2010-09-14T18:02:15.667 回答
1

在使用memcached作为数据库的缓存时,用户必须保证数据库和缓存之间的数据一致性。如果您想扩大规模并添加更多服务器,即使一切正常,也有可能与数据库不同步。

相反,您可以考虑Hazelcast。从 1.9 开始,它还支持 memcache 协议。与 memcached 相比,Hazelcast 希望您实现 Map Persister,并且只更新数据库以获取更新的条目。这样您就不必处理“检查缓存,如果数据更改更新数据库”之类的东西。

于 2010-09-14T09:01:52.270 回答