10 | 存储模块:如何用Redis解决推荐系统特征的存储问题?
10 | 存储模块:如何用Redis解决推荐系统特征的存储问题?
讲述:王喆
时长13:24大小12.23M
推荐系统存储模块的设计原则
SparrowRecsys 的存储系统方案
你需要知道的 Redis 基础知识
Sparrow Recsys 中的 Redis 部分的实践流程
小结
课后思考
赞 16
提建议
精选留言(25)
- An2020-10-26redis keys命令不能用在生产环境中,如果数量过大效率十分低,导致redis长时间堵塞在keys上。
作者回复: 非常好的点。生产环境我们一般选择提前载入一些warm up物品id的方式载入物品embedding。这里做了一个简化,推荐大家参考这条评论,多谢!
共 2 条评论52 - AIGeek2020-10-26Redis value 可以用pb格式存储, 存储上节省空间. 解析起来相比string, cpu的效率也应该会更高
作者回复: 生产环境确实经常使用protobuf进行压缩,非常好的经验。
共 4 条评论39 - 范闲2020-11-261.redis这种缓存中尽量放活跃的数据,存放全量的embedding数据,对内存消耗太大。尤其物品库,用户embedding特别多的情况下。 2.分布式kv可以做这种embedding的存储 3.关于embedding的编码可以用pb来解决。embedding维度太大的时候,redis里的数据结构占用空间会变大,因为除了embedding本身的空间,还有数据结构本身占用的空间。
作者回复: 优秀。非常好的经验之谈,推荐其他同学学习。
共 4 条评论31 - fsc20162020-11-04老师,有俩个问题 1,文中关于RecForYou,是来一个用户访问,就把用户的embding存入推荐服务器内存,如果一个短时间一下来百万级用户,都存入服务器内存,这样会不会出问题,优化的话应当也可以对用户分级,活跃用户存下来,非活跃其他还是从Redis实时读取用户特征。 2,RecForYou中,给用户推荐电影,使用的用户embding和候选电影embding的余弦距离来排序,这俩个不同维度embding计算余弦相似度有意义嘛,还是因为本例子中用户embding由其看过的电影embbding 相加来的。所以这么做嘛展开
作者回复: 这两个问题都是非常好的问题,推荐其他同学思考。 1. 我们并没有把用户embedding保存在内存中,只是把item embedding提前load到内存里,所以其实不存在这样的情况。但你说的也是非常好的用户数据缓存的方案,我们一般会指定一个用户内存区域的大小,用FIFO的方案来缓存,这样内存用完了,就自动把早进来的用户pop出去。 另外分级的想法也非常好,如果有条件可以判断活跃用户,可以尽量选择活跃用户进行缓存。 2、你说的没错,用户emb和物品emb必须在一个向量空间内才能够做相似度计算。咱们项目中的用户emb是通过item emb平均生成的,所以可以这样计算。
20 - Lucifer2020-11-23向量索引faiss共 1 条评论7
- Geek_ddf8b12020-12-06用户特征分为长期兴趣特征和实时兴趣特征,长期兴趣特征一般是按天更新,实时特征可能按分钟或者秒级更新。请问实际项目中是长期特征按天更新写入redis,短期特征分钟级更新写入redis这样吗?
作者回复: 是这样,长期兴趣或这说周期比较长的metadata特征,按天写入特征数据库,实时特征进行实时更新。
6 - shenhuaze2020-11-04王老师,想问一下关于全量特征存储的数据库选型。业界用来存储全量特征的最主流的数据库是什么?Cassandra吗?HBase是否合适?
作者回复: 一般来说Cassandra的读性能会比HBase好很多,包括类似的AWS用的dynamoDB,现在用得多一些。 但也有对HBase的读性能做优化的,比如加缓存,做一些读取命令的优化,但作为服务线上的实时数据库,确实会用的少一些。
6 - Geek_b6bf292021-01-08老师你好,关于这一步 “我们完全可以把所有物品特征阶段性地载入到服务器内存中,大大减少 Redis 的线上压力。” 该如何具体操作呢。比如离线计算每6个小时更新物品特征,是不是在线服务也要重启更新,把最新的物品特征载入服务器?还是有更好的方法,可以支持热更新,不用重启在线服务?
作者回复: 在线服务内部可以有各种载入和维护feature的缓存逻辑。最简单比如设置一个timer去定期load热门的新feature。不用重启服务器。
5 - 张宏宇2021-03-17老师,我想问的是特征在更新的时候可能发生数据不一致的情况,比如用户特征先更新,物品特征后更新,在两个特征更新过程中线上服务读取特征数据的时候,可能用户特征是新的,物品特征是老的,不知道老师是否遇到过这样的问题以及如何解决的,谢谢!
作者回复: 这个肯定会存在。但我觉得要点还得具体问题具体分析,要看一下物品和用户特征有没有必要完全协同的更新,比如物品历史ctr这个特征,完全可以独立更新。 如果一定要一起更新,那么就只能在streaming平台上每次都协同更新这些特征。 我个人觉得有一些秒级、分钟级的差异,影响不会那么大,没有那么关键。
4 - Jackie2020-11-03文中说把物品特征放到服务器中,“我们完全可以把所有物品特征阶段性地载入到服务器内存中,大大减少 Redis 的线上压力。”,那如果物品也特别多,不也放不下吗?
作者回复: 那按照咱们这节课讲的分级存储的原则,内存里面放不下,应该怎么解决这个问题呢?能不能放一些经常访问的在内存里,长尾的放在其他地方?或者经常用的特征放内存里等等方法?
共 2 条评论2 - 浣熊当家2020-10-26有个很小白的问题请问老师, 我们在IntelliJ的Maven porject里用到的工具比如spark, redis, 这些需要我们额外下载安装到电脑上吗?还是说在Maven项目中已经通过代码添加依赖,就已经完成了安装?
作者回复: spark本质上是一个java lib,所以可以被maven安装依赖。 redis是一个数据库,需要按照文中的方式安装到电脑上。
2 - 浣熊当家2020-10-26请问老师,文中的两部分redis相关的代码,可以在Maven项目中找到吗?老师可不可以提供以下路径信息方便找到?
作者回复: 可以,请参照 com.wzhe.sparrowrecsys.offline.spark.embedding.Embedding中的trainItem2vec函数 以及com.wzhe.sparrowrecsys.online.datamanager.DataManager中的loadMovieEmb函数
2 - dandy2022-01-28老师你们这边是把item embedding存到内存,那用户存的是原始特征还是embedding后的存到redis呢,如果是原始特征是否需要特征抽取呢。一般现在业内是怎么处理的。 我们内部系统是item和user都是存的原始特征,后面做特征抽取,在embedding1
- 胡译匀2021-01-10请问如何调试scala程序?网上找了半天也没靠谱的,谢谢。
作者回复: scala 程序本质上就是java程序,在IDEA里面的调试方法和java一样
1 - romance2020-12-17老师,Embedding 主函数要装了Spark才能跑起来吧?
作者回复: 只要正确安装了scala并且配置好了maven环境,能够引入spark的lib,就可以跑起来。项目的默认环境是单机环境,不需要任何外部spark环境
1 - Geek_ddf8b12020-12-06为保证线上请求特征和线下日志特征数据一致性,用户线上请求时用户特征和物品特征是从redis查询得到后写到日志文件吗? 这时用户的实时特征比如过去几分钟点击的物品序列特征是从kafka读取还是从redis读取? 还是kafka发送用户的行为物品序列数据每隔几分钟写入redis,然后线上请求获取特征做预估打分和写特征数据到日志文件统一从redis读取?展开
作者回复: 不可能直接从kafka读取的,线上系统不可能接入任何流处理系统。需要以redis这类特征数据库作为所有数据的线上中转存储。
1 - ꧁꫞꯭R꯭e꯭i꯭r꯭i...2023-01-20 来自江西ssdb如何?
- 雨尽书声响2022-09-01 来自北京老师您好,文中说把物品特征放到服务器中,“我们完全可以把所有物品特征阶段性地载入到服务器内存中,大大减少 Redis 的线上压力。”,物品特征存入内存大约多少条会比较合适那
- Calmness2022-02-26老师,服务器内存不够的时候放在内存数据库,但是内存数据库不也全部都是建立在内存的基础上的吗?那如果服务器内存不够了放在内存数据库里不也不够吗?还有那个阶段性的物品特征该怎么理解呀?能举个例子吗
- Geek_ddf8b12021-09-02老师 请教一下 推荐项目中用户有几千万,几千万用户的特征(部分是用户实时行为特征)全部存在redis中,key太多会导致redis查询性能直线下降,请问这个问题如何解决?
作者回复: 分级cache,区分活跃用户非活跃用户