我正在创建一个重写查找结构以将 ID 从字符串命名空间映射到数字索引。我这样做的原因是字符串 ID 很大(数百字节),有数百万个,并且它们在 Redis 中用于许多不同的对象。将复杂的字符串 ID 映射到更简洁的命名空间将有助于符合常驻内存设计考虑因素。
实现上述目标的一种方法是插入到某个结构中,如果要插入的键不存在,则接收回一个自动递增的整数。如果它确实存在,则只需接收回先前关联的整数即可。
通过 Python 表达上述内容的一种非原子方式如下:
def get_or_set(d, item):
if item not in d:
d[item] = len(d)
return d[item]
插入操作将是并行的,因此解决方案需要是原子的。
我可以看到在 Redis 中使用事务中的多个命令执行上述操作的方法。我想知道是否只有一个命令?
单个命令不是严格要求,而是令人愉快的要求。上面的任务并不少见,所以我认为 Redis 可能添加了直接支持——我仍在学习命令套件,很容易忽略了一些东西。
最佳答案
可能有多种方法可以完成您想要的操作,所以我将解释其中一种比较简单的方法。所有这些都没有单一的 Redis 命令,但您可以组合可用的命令来巧妙地解决这个问题。
我们将使用单个 Redis 哈希来存储所有数据。哈希存储在名为“数据”的键中,每个字符串 ID 都有一个字段,其值为数字 ID。哈希中的一个附加字段称为“current_id”,假设这不是字符串 ID 之一,它将存储最后一个数字 ID。
在不关心原子性的情况下,您可以这样做(r 是您与 Redis 的连接):
def get_or_set(item):
kid = r.hget('data', item)
if kid is None:
kid = r.hincrby('current_id', 1)
r.hset('data', item, kid)
return kid
要添加原子性,您需要将其迁移到 Lua 脚本。该脚本将在服务器端自动运行,以便处理任何可能的竞争条件。
SCRIPT = """
local kid = redis.call('HGET', KEYS[1], ARGV[1])
if not kid then
kid = redis.call('HINCRBY', KEYS[1], 'current_id', 1)
redis.call('HSET', KEYS[1], ARGV[1], kid)
end
return kid
"""
SHA = r.script_load(script)
def get_or_set(item):
return r.evalsha(SHA, 1, 'data', item)
关于redis - 在单个命令中插入原子索引重写结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43899738/
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions
您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应
我发现自己需要这个。假设cart是一个包含用户列表的模型。defindex_of_itemcart.users.each_with_indexdo|u,i|ifu==current_userreturniendend获取此类关联索引的更简单方法是什么? 最佳答案 indexArray上的方法与您的index_of_item方法相同,例如cart.users.index(current_user)返回数组中第一个对象的索引==给obj。如果未找到匹配项,则返回nil。 关于ruby-on-
我有一个问题。我想从另一个ruby脚本运行一个ruby脚本并捕获它的输出信息,同时让它也输出到屏幕。亚军#!/usr/bin/envrubyprint"Enteryourpassword:"password=gets.chompputs"Hereisyourpassword:#{password}"我运行的脚本文件:开始.rboutput=`runner`putsoutput.match(/Hereisyour(password:.*)/).captures[0].to_s正如您在此处看到的那样,存在问题。在start.rb的第一行,屏幕是空的。我在运行程序中看不到“输入您的密
因此,当我遵循MichaelHartl的RubyonRails教程时,我注意到在用户表中,我们为:email属性添加了一个唯一索引,以提高find的效率方法,因此它不会逐行搜索。到目前为止,我们一直在根据情况使用find_by_email和find_by_id进行搜索。然而,我们从未为:id属性设置索引。:id是否自动索引,因为它在默认情况下是唯一的并且本质上是顺序的?或者情况并非如此,我应该为:id搜索添加索引吗? 最佳答案 大多数数据库(包括sqlite,这是RoR中的默认数据库)会自动索引主键,对于RailsMigration
有这样的事吗?我想在Ruby程序中使用它。 最佳答案 试试这个http://csl.sublevel3.org/jp2a/此外,Imagemagick可能还有一些东西 关于ruby-是否有将图像文件转换为ASCII艺术的命令行程序或库?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/6510445/
我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195