我发现Redis对我的项目有很好的功能(webapp的自动完成后端)。基本上,它是我的全文搜索引擎。现在我正在寻找Redis的替代品,因为我无法将整个数据集保存在内存中。
我像这样创建我的Redis商店(找不到这个想法的信用链接):
['wor', 'ord', 'rds']
)ZADD chunk weight items_id
)SET items_id items_hash_in_json
)搜索的工作原理如下:
ZINTERSTORE
和ZRANGEBYSCORE
的组合)简单明了。非常有效和快速。在这样的流程中仍有一些较小的缺点,但大多数情况下我觉得我的域名拥有恰当的工具和正确的数据类型。
主要问题是:它需要太多内存。我在数据库中有大约600K项目,并且在'索引'后我将它们在40个字符后减少,但它仍需要2.5GB RAM。这项任务有点多了。数据集会增长,但不会太快和太快,但仍然存在。
我现在看了一些NoSQL商店,我没有像Redis那样遇到类似的方法和工具。也许这是因为我现在看起来每件作品的锤子,但我觉得与其他NoSQL商店我需要实现自己这样的功能(排序列表,找到它们的交集,简单的键值作为二进制字符串,插入数据死简单,简单协议/ API和简单客户端。)
我也想要Perl绑定,但是如果协议非常简单(如CoachDB的REST),则不是强制性的。
您是否知道使用其他NoSQL产品实现我的解决方案的工具?
另一方面,我已经寻找完全不同的解决方案(如couchdb-lucene,但我想避免放弃上面描述的系统。
答案 0 :(得分:1)
HTTP缓存 我有一个可能的解决方案,我目前在我的网站上使用。我使用Nginx缓存自动完成查询与静态文件。 Nginx可以非常快速地提供静态文件。这是我在配置中的示例行。
http {
fastcgi_cache_path /var/cache/nginx levels=1:2
keys_zone=tt:600m
inactive=7d max_size=10g;
fastcgi_temp_path /var/cache/nginx/tmp;
}
此块描述了存储文件的路径。 level是多少目录深,1:2就足够了。我的区域名为tt,无论你想要什么,都可以命名。随后是到期时间。
location ~ /tt/(.+)\.php$ {
try_files $uri /index.php?$args;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
#Caching parameters
fastcgi_cache tt;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_valid 200 302 304 30m;
fastcgi_cache_valid 301 1h;
fastcgi_cache_valid any 5m;
fastcgi_cache_use_stale error timeout invalid_header updating http_500;
}
位置块将包含缓存参数。因此,任何带有URI /tt/.*.php的内容都将被缓存。 URI +查询字符串将成为缓存键。
如果您不使用Nginx,相同的概念可能适用于其他网络服务器。我希望这会有所帮助。
修改强>
来自评论: 使用index作为普通文件似乎比SQL查询慢。不过,我还没有对它们进行基准测试。
Nginx的缓存命中将如下所示:
- > Nginx - >文件
小姐:
- > Nginx - > php / python / ruby - >分贝(redis的/ MySQL的/其他)
第一条路径可能看起来比较慢,因为您会想到diskio,但事实并非如此,操作系统会自动缓存经常访问的文件。因此,当Nginx升温时,只需点击你的PHP后端说“Hello world”就会比较慢。我提出这个主张是因为它就像提供静态文件一样。
实际命中/未命中率取决于应用程序,数据和配置。根据我的经验,人们使用了很多相同的搜索词,所以你可能不会有600k文件。即使你这样做并没有真正受到伤害,Nginx会为你管理它们。如果您的数据发生很大变化并且您希望搜索能够快速反映这些变化,则此方法不是很好。你必须设置一个短暂的过期时间,这会导致更多的失误。
Redis Zip Lists / Hashes http://redis.io/topics/memory-optimization
如果您仍需要排序集,请确保链接中的配置设置设置得足够高,以满足您的数据集需求。如果您能够使用哈希值,则可以使用在该页面上显示较低的算法来节省大量内存。我认为你可以在将item_id链接到json字符串时使用它。
答案 1 :(得分:0)
只是简单的想法可能对你有用。它不是您问题的直接和准确答案。
我认为您的大部分数据或重要部分都位于这些JSON文档中。在这种情况下,我建议您稍微改变一下您的数据基础架构:为了保留Redis的所有好处,您应该使用相同的前两个步骤进行创建和搜索,但改变你的第三步。不要使用Redis来存储这些JSON文档,只需将它们移动到您喜欢/使用过的数据库的简单索引表即可。这样您只需处理块和密钥并执行Redis提供的操作,但在步骤3中,您将获取item_id列表并从数据库中检索JSON数据。可能SELECT ... WHERE item_id IN(...)
就足够了。