对于单主机 Node.js 生产应用程序来说,什么是好的会话存储?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8749907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is a good session store for a single-host Node.js production app?
提问by Nils
I'm using Node's Express w/ Connect middleware. Connect's memory session store isn't fit for production:
我正在使用 Node 的 Express 和 Connect 中间件。Connect 的内存会话存储不适合生产:
Warning: connection.session() MemoryStore is not designed for a production environment, as it will leak memory, and obviously only work within a single process.
Warning: connection.session() MemoryStore is not designed for a production environment, as it will leak memory, and obviously only work within a single process.
For larger deployments, mongo or redis makes sense.
对于更大的部署,mongo 或 redis 是有意义的。
But what is a good solution for a single-host app in production?
但是对于生产中的单主机应用程序来说,什么是好的解决方案?
回答by balupton
Spent the day looking into this. Here are the options I've discovered. Requests/second are performed via ab -n 100000 -c 1 http://127.0.0.1:9778/on my local machine.
花了一天时间研究这个。以下是我发现的选项。请求/秒是通过ab -n 100000 -c 1 http://127.0.0.1:9778/我的本地机器执行的。
- no sessions - fast (438 req/sec)
- cookieSession: requires no external service, minor speed impact (311 req/sec) - fastest, sessions will expire with the cookie (customised by
maxAge) - connect-redis: requires redis server, large speed impact (4 req/sec with redis2go and redisgreen) - faster than mongo, sessions will be deleted after a while (customised by
ttl) - connect-mongo- requires mongodb server, large speed impact (2 req/sec with mongohq) - slower than redis, requires manual
clear_intervalto be set to cleanup sessions
- 没有会话 - 快速(438 请求/秒)
- cookieSession:不需要外部服务,对速度影响较小(311 req/sec) - 最快,会话将随着 cookie 过期(由 定制
maxAge) - connect-redis:需要 redis 服务器,速度影响很大(redis2go 和 redisgreen 为 4 req/sec) - 比 mongo 快,会话将在一段时间后被删除(由 自定义
ttl) - connect-mongo- 需要 mongodb 服务器,速度影响很大(mongohq 为 2 req/sec) - 比 redis 慢,需要手动
clear_interval设置清理会话
Here is the coffeescript I used for cookieSession:
这是我用于 cookieSession 的咖啡脚本:
server.use express.cookieSession({
secret: appConfig.site.salt
cookie: maxAge: 1000*60*60
})
Here is the coffeescript I use for redis:
这是我用于 redis 的咖啡脚本:
RedisSessionStore ?= require('connect-redis')(express)
redisSessionStore ?= new RedisSessionStore(
host: appConfig.databaseRedis.host
port: appConfig.databaseRedis.port
db: appConfig.databaseRedis.username
pass: appConfig.databaseRedis.password
no_ready_check: true
ttl: 60*60 # hour
)
server.use express.session({
secret: appConfig.site.salt
cookie: maxAge: 1000*60*60
store: redisSessionStore
})
Here is my coffeescript for mongo:
这是我的 mongo 咖啡脚本:
server.use express.session({
secret: appConfig.site.salt
cookie:
maxAge: 100*60*60
store: new MongoSessionStore({
db: appConfig.database.name
host: appConfig.database.host
port: appConfig.database.port
username: appConfig.database.username
password: appConfig.database.password
auto_reconnect: appConfig.database.serverOptions.auto_reconnect
clear_interval: 60*60 # hour
})
})
Now of course, the remote redis and mongo databases will be slower than their local equivalents. I just couldn't get the local equivalents working, especially considering the installation and maintenance time for me was far more than what I was willing to invest when compared with hosted remote alternatives, something I feel is true for others too hence why these hosted remote database services exist in the first place!
当然,远程 redis 和 mongo 数据库会比它们的本地数据库慢。我只是无法让本地等效项工作,特别是考虑到与托管远程替代方案相比,我的安装和维护时间远远超过我愿意投资的时间,我觉得其他人也是如此,因此为什么这些托管远程数据库服务首先存在!
For local database benhmarks, see @Mustafa's answer.
有关本地数据库基准,请参阅 @Mustafa的回答。
Happy for someone to edit this answerto add their local database benchmarks to the mix.
很高兴有人编辑此答案以将其本地数据库基准添加到组合中。
回答by Mustafa
Since the accepted answer is only connecting to remote hosts, it is obvious that it will be always slower than localhost. Even if it is the next computer in your home, it would take milliseconds to read from that computer, but local memory takes only nanoseconds. You should compare them by using locally installed servers.
由于接受的答案仅连接到远程主机,很明显它总是比 localhost 慢。即使它是您家中的下一台计算机,从该计算机读取也需要几毫秒,而本地内存只需要纳秒。您应该使用本地安装的服务器来比较它们。
Here are my results from my local pc: You see, redis is almost as fast as in-memory in under high load. You can clone my the repo that these test codes are available: https://github.com/mustafaakin/express-session-store-benchmark
这是我在本地电脑上的结果:你看,在高负载下,redis 几乎和内存中一样快。您可以克隆我的 repo,这些测试代码可用:https: //github.com/mustafaakin/express-session-store-benchmark
Concurrency: 1
none 4484.86 [#/sec]
memory 2144.15 [#/sec]
redis 1891.96 [#/sec]
mongo 710.85 [#/sec]
Concurrency: 10
none 5737.21 [#/sec]
memory 3336.45 [#/sec]
redis 3164.84 [#/sec]
mongo 1783.65 [#/sec]
Concurrency: 100
none 5500.41 [#/sec]
memory 3274.33 [#/sec]
redis 3269.49 [#/sec]
mongo 2416.72 [#/sec]
Concurrency: 500
none 5008.14 [#/sec]
memory 3137.93 [#/sec]
redis 3122.37 [#/sec]
mongo 2258.21 [#/sec]
The session used pages are very simple pages;
会话使用的页面是非常简单的页面;
app.get("/", function(req,res){
if ( req.session && req.session.no){
req.session.no = req.session.no + 1;
} else {
req.session.no = 1;
}
res.send("No: " + req.session.no);
});
Redis store config:
Redis 存储配置:
app.use(express.session({
store: new RedisStore({
host: 'localhost',
port: 6379,
db: 2,
}),
secret: 'hello'
}));
Mongo store config:
Mongo 商店配置:
app.use(express.cookieParser());
app.use(express.session({
store: new MongoStore({
url: 'mongodb://localhost/test-session'
}),
secret: 'hello'
}));
回答by kgilpin
Another good option is memcached. The session states are lost if memcached is restarted, but there is virtually never any reason to do that. You can leave the cache running all the time even when you restart your app server. Access to the session data is virtually instantaneous and memcached will run happily with whatever (appropriate) amount of memory you give it. And I've never seen memcached crash (on Linux).
另一个不错的选择是 memcached。如果 memcached 重新启动,会话状态就会丢失,但实际上没有任何理由这样做。即使重新启动应用程序服务器,您也可以让缓存一直运行。对会话数据的访问几乎是即时的,并且 memcached 将在您提供的任何(适当的)内存量下愉快地运行。而且我从未见过 memcached 崩溃(在 Linux 上)。
https://github.com/elbart/node-memcache
https://github.com/elbart/node-memcache
Things to keep in mind about memcached generally:
关于 memcached 一般要记住的事情:
- Never have whitespace in your cache keys
- Be aware that there is a maximum cache key length, including any namespace prefix you might use. If your cache key is too long, use a 1-way hash of it instead.
- 缓存键中永远不要有空格
- 请注意,存在最大缓存键长度,包括您可能使用的任何命名空间前缀。如果您的缓存键太长,请改用它的 1 向哈希。
Neither of these should be an issue with session storage; just with generalized caching.
这些都不应该是会话存储的问题;只是使用通用缓存。
回答by greenimpala
I've gone with a MongoDB session store using connect-mongo.
我已经使用connect-mongo使用了 MongoDB 会话存储。
Install with npm install connect-mongoand replace the existing MemoryStore with
安装npm install connect-mongo并替换现有的 MemoryStore
app.use(express.session({ store: new MongoStore({ db: 'some-database' }) }));
app.use(express.session({ store: new MongoStore({ db: 'some-database' }) }));
It manages the database side of sessions automatically.
它自动管理会话的数据库端。
回答by Timothy Meade
I would still use Redis even for local development. This is helpful because it stores the session even when you restart the Node application, keeping your browser session logged in. Redis by default saves the session in memory, same as connect's memory store is simple to configure (I just run it in screen along with my node apps) can support multiple applications if you just use a different database or session value in the configuration.
即使在本地开发中,我仍然会使用 Redis。这很有用,因为即使您重新启动 Node 应用程序,它也会存储会话,保持浏览器会话处于登录状态。默认情况下,Redis 将会话保存在内存中,就像 connect 的内存存储一样易于配置(我只是在屏幕中运行它我的节点应用程序)可以支持多个应用程序,如果您只是在配置中使用不同的数据库或会话值。
回答by nimrodm
I'm just exploring node.js myself, but if you don't need to store a lot of information in the session object -- you might want to explore secure cookies.
我自己只是在探索 node.js,但如果您不需要在会话对象中存储大量信息——您可能想要探索安全 cookie。
Secure cookies store session information as part of the cookie that the browser stores and forwards with each request. They are encrypted to prevent a user from forging a valid cookie.
安全 cookie 将会话信息存储为 cookie 的一部分,浏览器存储和转发每个请求。它们被加密以防止用户伪造有效的 cookie。
The advantage is that you don't have to maintain state at the server -- this solution scales well and is simple to implement.
优点是您不必在服务器上维护状态——此解决方案可扩展且易于实现。
The disadvantage is that you can only store up to about 4KB and that data gets sent to the server on everyrequest (But you can have multiple fictitious domains pointing at your server so you don't impose that baggage on publicly visible static content, for example).
缺点是您最多只能存储大约 4KB,并且每次请求都会将数据发送到服务器(但是您可以有多个虚拟域指向您的服务器,因此您不会将这些包袱强加给公开可见的静态内容,因为例子)。
Searching the web it seems like there are at least two implementations of secure cookies for node.js. Not sure how production ready they are, though:
在网上搜索,似乎至少有两种用于 node.js 的安全 cookie 实现。不过,不确定它们的生产准备情况:
https://github.com/benadida/node-client-sessions/blob/master/lib/client-sessions.js
https://github.com/benadida/node-client-sessions/blob/master/lib/client-sessions.js
回答by davidm_uk
I appreciate that this is an old question, but I came across it while searching for a solution to a similar problem. I had already decided to use memcached for session storage on Linux (with connect-memcached), but I also required the ability to run on Windows. I spent a while trying to find an in-memory session storage for a single-process node app. Redis and Memcached don't appear to be well-supported on Windows, and I didn't want the additional complexity of their installation.
我很欣赏这是一个老问题,但我在寻找类似问题的解决方案时遇到了它。我已经决定在 Linux 上使用 memcached 进行会话存储(使用connect-memcached),但我还需要能够在 Windows 上运行。我花了一段时间试图为单进程节点应用程序寻找内存会话存储。Redis 和 Memcached 在 Windows 上似乎没有得到很好的支持,我不希望它们的安装增加额外的复杂性。
I found session-memory-storein another Stack Overflow thread, which looks good but significantly increased the size of my dependencies.
我在另一个 Stack Overflow 线程中发现了session-memory-store,它看起来不错,但显着增加了我的依赖项的大小。
Finally, I found memorystorein the documentation for express-session. I had missed it originally due to the similarly of its name to the default MemoryStore, but it's exactly what I was looking for:
最后,我在express-session的文档中找到了memorystore。由于其名称与 default 相似,我最初错过了它,但这正是我正在寻找的:MemoryStore
express-session full featured MemoryStore module without leaks!
express-session 全功能 MemoryStore 模块,无泄漏!
I'm now using connect-memcached when running in a cluster (on Linux only), and memorystore when running a single process (on Linux or Windows).
我现在在集群中运行时使用 connect-memcached(仅在 Linux 上),在运行单个进程时使用 memorystore(在 Linux 或 Windows 上)。
I thought it worth posting this as another answer, just in case anyone else makes the mistake of missing memorystore as I initially did.
我认为值得将此作为另一个答案发布,以防万一其他人像我最初所做的那样犯了缺少 memorystore 的错误。
回答by llambda
Check out my benchmarks at https://github.com/llambda/express-session-benchmarksshowing comparisons of different session implementations.
在https://github.com/llambda/express-session-benchmarks查看我的基准测试,显示了不同会话实现的比较。

