Redis的srandmember有问题

Redis 的 srandmember 方法的结果不正常。

现象

观察

在Redis的集合数据类型中有一个函数叫做srandmember,但是我发现这个函数的分布形式有些奇怪,所以我想记录一下作为备忘录。

什么时候会变得奇怪?

    • キーが数値の場合には問題が無い。

 

    • キーが文字列に確率がおかしくなる。

 

    • キーが文字列でも確率がおかしくならない場合がある。

 

    • 文字列のときの条件はわからない。(そこまで調べる気もあまりない

 

    キーは数値を使った方がいいよ

再现代码

#!/usr/bin/env perl
use 5.16.2;
use strict;
use warnings;
use utf8;

use Redis::Fast;

my $redis = Redis::Fast->new;

my $elements_count = 5;
my $try_count = 1000;
my $result;

$redis->del("test");
$result = {};

say "### 要素数 $elements_count 数値の場合";
say "|キー名|取得数|確率|";
say "| ---- | ---- | ---- |";
$redis->sadd("test" , $_) for 1..$elements_count;
$result->{$redis->srandmember("test")}++ for 1..$try_count;
for(1..$elements_count){
    say "|" . (join " | " , sprintf("%-4s", $_) , sprintf("%-3s" , $result->{$_}) , (100 * $result->{$_} / $try_count) . "%") . "|";
}

$redis->del("test");
$result = {};

say "";
say "### 要素数 $elements_count 文字列の場合";
say "キー名|取得数|確率";
$redis->sadd("test" , "test$_") for 1..$elements_count;
$result->{$redis->srandmember("test")}++ for 1..$try_count;
for(1..$elements_count){
    say "|" . (join " | " , sprintf("%-8s", "test$_") , sprintf("%-3s" , $result->{"test$_"}) , (100 * $result->{"test$_"} / $try_count) . "%") . "|";
}

结果

    • 要素数5個,試行回数は1000回の時、文字列の場合の取得確率が均等になっていない

 

    • 要素数10個,試行回数は1000回の時、文字列の取得が均等になっている

 

    要素数20個,試行回数10万回の時、均等になっていない

要素的数量为5时

キー名取得数確率119519.5%220920.9%320920.9%419519.5%519219.2%

如果是一个包含5个元素的字符串的话

キー名取得数確率test112512.5%test212812.8%test324924.9%test423123.1%test526726.7%

如果要素的数量是10,并且是数字。

キー名取得数確率110710.7%2919.1%310310.3%4828.2%510310.3%6939.3%710310.3%812712.7%9949.4%10979.7%

如果要素数为10的话

キー名取得数確率test110610.6%test210310.3%test310710.7%test4969.6%test5898.9%test6999.9%test710310.3%test8787.8%test9959.5%test1012412.4%

如果要素数量为20个且为数字的情况下

キー名取得数確率150355.035%250515.051%350505.05%449514.951%551485.148%650825.082%750735.073%850225.022%949224.922%1049834.983%1148704.87%1249294.929%1348974.897%1449244.924%1549934.993%1649514.951%1750565.056%1850245.024%1949654.965%2050745.074%

如果是一个由20个元素组成的字符串的情况。

キー名取得数確率test166996.699%test265606.56%test333843.384%test433833.383%test565936.593%test666846.684%test765656.565%test833313.331%test966446.644%test1067856.785%test1122552.255%test1233593.359%test1366906.69%test1467406.74%test1533803.38%test1621932.193%test1766816.681%test1866406.64%test1932323.232%test2022022.202%
bannerAds