Programing

단일 호스트 Node.js 프로덕션 앱에 적합한 세션 저장소는 무엇입니까?

lottogame 2020. 11. 10. 07:44
반응형

단일 호스트 Node.js 프로덕션 앱에 적합한 세션 저장소는 무엇입니까?


저는 Node 's Express w / 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.

대규모 배포의 경우 mongo 또는 redis가 적합합니다.

그러나 프로덕션의 단일 호스트 앱에 적합한 솔루션은 무엇입니까?


이것을 조사하는 데 하루를 보냈습니다. 내가 발견 한 옵션은 다음과 같습니다. 초당 요청 ab -n 100000 -c 1 http://127.0.0.1:9778/은 내 로컬 컴퓨터 를 통해 수행됩니다 .

  • 세션 없음-빠름 (438 요청 / 초)
  • cookieSession : 외부 서비스 필요 없음, 약간의 속도 영향 (311 요청 / 초)-가장 빠르며 세션은 쿠키와 함께 만료됩니다 (에서 사용자 지정 maxAge)
  • connect-redis : redis 서버 필요, 큰 속도 영향 (redis2go 및 redisgreen의 경우 4 req / sec)-mongo보다 빠르며 잠시 후 세션이 삭제됩니다 (에서 사용자 지정 ttl)
  • connect- mongo - mongodb 서버 필요, 큰 속도 영향 (mongohq의 경우 2 req / sec)-redis보다 느림, clear_interval세션 정리를 위해 수동 설정 필요

다음은 cookieSession에 사용한 커피 스크립트입니다.

server.use express.cookieSession({
    secret: appConfig.site.salt
    cookie: maxAge: 1000*60*60
})

redis에 사용하는 coffeescript는 다음과 같습니다.

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
})

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
    })
})

물론 원격 redis 및 mongo 데이터베이스는 로컬 데이터베이스보다 느립니다. 특히 호스팅 된 원격 대안과 비교할 때 제가 투자하고자하는 것보다 훨씬 더 많은 설치 및 유지 관리 시간을 고려할 때 로컬 등가물이 작동하도록 할 수 없었습니다. 데이터베이스 서비스는 애초에 존재합니다!

로컬 데이터베이스 benhmark에 대해서는 @Mustafa 의 답변을 참조하십시오 .

누군가 가이 답변편집 하여 로컬 데이터베이스 벤치 마크를 혼합에 추가하게되어 기쁩니다.


허용되는 대답은 원격 호스트에만 연결하기 때문에 항상 localhost보다 느릴 것입니다. 집에있는 다음 컴퓨터라도 해당 컴퓨터에서 읽는 데 밀리 초가 걸리지 만 로컬 메모리는 나노초 만 걸립니다. 로컬에 설치된 서버를 사용하여 비교해야합니다.

내 로컬 PC의 결과는 다음과 같습니다. redis는 부하가 높을 때 메모리 내만큼 빠릅니다. 이 테스트 코드를 사용할 수있는 내 저장소를 복제 할 수 있습니다. 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] 

세션 사용 페이지는 매우 단순한 페이지입니다.

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 스토어 구성 :

app.use(express.session({
    store: new RedisStore({
        host: 'localhost',
        port: 6379,
        db: 2,
        }),
    secret: 'hello'
}));

Mongo 스토어 구성 :

app.use(express.cookieParser());
app.use(express.session({
    store: new MongoStore({
        url: 'mongodb://localhost/test-session'
    }),
    secret: 'hello'
}));

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).

https://github.com/elbart/node-memcache

Things to keep in mind about memcached generally:

  • 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.

Neither of these should be an issue with session storage; just with generalized caching.


I've gone with a MongoDB session store using connect-mongo.

Install with npm install connect-mongo and replace the existing MemoryStore with

app.use(express.session({ store: new MongoStore({ db: 'some-database' }) }));

It manages the database side of sessions automatically.


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.


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.

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.

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 every request (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).

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:

https://github.com/benadida/node-client-sessions/blob/master/lib/client-sessions.js

https://github.com/caolan/cookie-sessions


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.

I found session-memory-store in another Stack Overflow thread, which looks good but significantly increased the size of my dependencies.

Finally, I found memorystore in 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 full featured MemoryStore module without leaks!

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).

I thought it worth posting this as another answer, just in case anyone else makes the mistake of missing memorystore as I initially did.


Check out my benchmarks at https://github.com/llambda/express-session-benchmarks showing comparisons of different session implementations.

참고URL : https://stackoverflow.com/questions/8749907/what-is-a-good-session-store-for-a-single-host-node-js-production-app

반응형