node.js - Node.js/Express.js 中的 Redis Bitset 操作

标签 node.js redis express bitset

我对 Node.js 和 Redis 非常陌生。我阅读了这篇文章,并希望使用位集来存储我的 Express.js 应用程序的所有用户信息,如本文中所述:http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/

我遇到了一点麻烦。在我的函数中,我获取当前的年、月和日期,然后使用 client.setbit() 设置适当的键和值。但我怎样才能数出所有的 key 呢?我使用的是 Redis 2.4*,BITCOUNT 命令使用的是 2.6。还有其他办法吗?本文使用 Java 位集,所以这是另一回事。我不太明白。

例如,我如何使用 for 循环来计算所有设置为 1 的位?是否有任何操作可以计算位集的大小,所以我可以这样做:

for (var i = initial_offset; i < bitset_length; i++){
    if (i == 1){
        total_users++;
    }
}

还是我以完全错误的方式处理这件事?

最佳答案

您需要计算 Redis 中存储的给定字符串的位数。 基本上有两种方法可以做到这一点:

  • 您可以尝试使用 Redis 2.6 和新的 BITCOUNT/BITOP 操作在服务器端执行此操作。

  • 您可以检索整个字符串(包含所有位)并在客户端处理数据。在原始文章中,作者检索 Redis 字符串并将其转换为可以应用位级算法的 Java 位集。同样的策略可以应用于任何客户端、任何语言:你只需要找到一个好的库来处理位数组,或者自己实现一个(这并不难)。它适用于 Redis 2.2 或更高版本。

一种不太有效的策略是在客户端进行迭代并通过执行 GETBIT 命令来检查每个单独的位。这实在是太低效了。

对于 Node.js,您可能需要使用以下一些资源来实现第二个选项:

Node.js 不是一个非常好的环境来实现 CPU 消耗操作,但在最坏的情况下,如果您有非常大的位集,您仍然可以依赖从 Node.js 调用的高效 C++ 实现。你在 boost::dynamic_bitset 有一个很好的.

这是一个 Node.js 示例,其中包含一个非常简单(而且可能效率低下)的计数算法:

var redis = require('redis')
var rc = redis.createClient(6379, 'localhost', {return_buffers:true} );

var bitcnt = [ 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8]

function count(b)
{
  var cnt = 0
  for (i=0; i<b.length; ++i ) {
    cnt += bitcnt[ b[i] ]
  }
  return cnt
}

function fetch( callback )
{
  rc.get( 'mybitset', function(err,reply) {
     callback(reply)
  });
}

function fill( callback )
{
   rc.setbit( 'mybitset', 0, 1 )
   rc.setbit( 'mybitset', 10, 1 )
   rc.setbit( 'mybitset', 20, 1 )
   rc.setbit( 'mybitset', 60, 1, function(err,reply) {
      callback()
   });
}

rc.flushall( function(err,rr) {
   fill( function() {
      fetch( function(b) {
        console.log( "Count = ",count(b) );
      });
   })
})

请注意 {return_buffers:true} 选项用于确保 Redis 输出被处理为二进制数据(忽略可能的字符转换)。

关于node.js - Node.js/Express.js 中的 Redis Bitset 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11190116/

相关文章:

javascript - ~[Array].indexOf(key) 是做什么的?

node.js - 在 Jade View 中检查 session 变量

javascript - Node.js 回调

performance - Node API 占用 100% CPU,node-tick-processor 输出看起来很神秘

mysql - 获取与 Redis 中给定模式匹配的哈希的键数 (hlen) 的最大值

python - Django 和 Celery - 检查 GroupResult 是否准备就绪时出现关键错误

javascript - 来自 NodeJs 和 MySql 的嵌套 Json 响应

angularjs - 如何使用 Angular 或 Node JS 在现有 Excel 文件中写入

node.js - Mongoose 中的集合名称

kubernetes - Kubernetes 上的 Redis 主/从设置抛出错误 : BRPOPLPUSH { ReplyError: MOVED 2651