redis
数据库-Redis
微信加人php源码,vscode怎么安装依赖,ubuntu 跳转路径,tomcat10教程,爬虫股东,php数组中添加数组,罗湖seo优化推广费用,微擎网站的根目录,学校响应式网站模板lzw
Redis视频教学大型论坛社区源码,vscode如何显示网页,ubuntu 装mpb,tomcat开启了put,医疗新闻爬虫,php 去掉指定字符,seo自动推广软件哪个好用,qq工具网站源码下载,建筑公司网页模板lzw
场景说明评论源码php,vscode能设置什么字体,Ubuntu建模软件,怎么访问tomcat首页,高中考爬虫,php 代码追踪,短视频seo引流推广机构,网上的vip小说网站的代码,wordpress苗木模板lzw
今天我们来模拟一个这样的场景,我们在本地有多个文本文件,每个文件里面存了很多的32位的字符串作为用户的唯一标识,每个用户存做一行,假如我们每天都有非常大规模的用户,这样我们可能在工作中就存在需要对这些用户进行交集、并集或补集等处理,最简单的方式是通过Java中的集合来进行运算即可,比如通过HashSet来进行相应的一些运算,但是这样的运算存在一个局限性,那就是我们一般在JVM运行过程中初始的内存是有限的,这样如果全部在JVM内存中进行计算的话,很容易出现内存空间不足导致的OOM异常,那么我们今天来介绍一种拓展性更强的方式来进行这样的一些交并补的运算:通过Redis来实现数据的交集、并集、补集环境说明
Redis版本: Redis 6.0.6
Jedis版本: 4.2.2
工具类hutool版本: 5.8.0.M3
pom文件:
redis.clients jedis 4.2.2 cn.hutool hutool-all 5.8.0.M3
交并补计算
初始化常量
public class RedisCalculateUtils { static String oneFileString = "/Users/tmp/test-1.txt"; static String twoFileString = "/Users/tmp/test-2.txt"; static String diffFileString = "/Users/tmp/diff-test.txt"; static String interFileString = "/Users/tmp/inter-test.txt"; static String unionFileString = "/Users/tmp/union-test.txt"; static String oneFileCacheKey = "oneFile"; static String twoFileCacheKey = "twoFile"; static String diffFileCacheKey = "diffFile"; static String interFileCacheKey = "interFile"; static String unionFileCacheKey = "unionFile"; }
初始化数据到指定文件
/*** 初始化数据并写入文件中*/public static void writeFile() { File oneFile = new File(oneFileString); List fs = new ArrayList(10000); for (int i = 10000; i < 15000; i++) { String s = SecureUtil.md5(String.valueOf(i)); fs.add(s); } FileUtil.writeUtf8Lines(fs, oneFile); File twoFile = new File(twoFileString); fs.clear(); for (int i = 12000; i < 20000; i++) { String s = SecureUtil.md5(String.valueOf(i)); fs.add(s); } FileUtil.writeUtf8Lines(fs, twoFile); }
指定文件写入Redis
/*** 读取文件数据并写入Redis*/public static void writeCache() { try(Jedis jedis = new Jedis("127.0.0.1", 6379)) { Pipeline p = jedis.pipelined(); List oneFileStringList = FileUtil.readLines(oneFileString, "UTF-8"); for (String s : oneFileStringList) { p.sadd(oneFileCacheKey, s); } p.sync(); List twoFileStringList = FileUtil.readLines(twoFileString, "UTF-8"); for (String s : twoFileStringList) { p.sadd(twoFileCacheKey, s); } p.sync(); } catch (Exception e) { throw new RuntimeException(e); }}
差集的计算
/** * oneKey对应的Set 与 twoKey对应的Set 的差集 并写入 threeKey * @param oneKey 差集前面的集合Key * @param twoKey 差集后面的集合Key * @param threeKey 差集结果的集合Key */ public static void diff(String oneKey, String twoKey, String threeKey) { try(Jedis jedis = new Jedis("127.0.0.1", 6379)) { long result = jedis.sdiffstore(threeKey, oneKey, twoKey); System.out.println("oneKey 与 twoKey 的差集的个数:" + result); } catch (Exception e) { throw new RuntimeException(e); } }
差集计算结果写入到指定文件
/** * 将计算的差集数据写入到指定文件 */ public static void writeDiffToFile() { File diffFile = new File(diffFileString); try(Jedis jedis = new Jedis("127.0.0.1", 6379)) { Set result = jedis.smembers(diffFileCacheKey); FileUtil.writeUtf8Lines(result, diffFile); } catch (Exception e) { throw new RuntimeException(e); } }
交集的计算
/** * * @param cacheKeyArray 交集集合Key * @param destinationKey 交集集合结果Key */ public static void inter(String[] cacheKeyArray, String destinationKey) { try(Jedis jedis = new Jedis("127.0.0.1", 6379)) { long result = jedis.sinterstore(destinationKey, cacheKeyArray); System.out.println("cacheKeyArray 的交集的个数:" + result); } catch (Exception e) { throw new RuntimeException(e); } }
交集计算结果写入指定文件
/** * 将计算的交集数据写入到指定文件 */ public static void writeInterToFile() { File interFile = new File(interFileString); try(Jedis jedis = new Jedis("127.0.0.1", 6379)) { Set result = jedis.smembers(interFileCacheKey); FileUtil.writeUtf8Lines(result, interFile); } catch (Exception e) { throw new RuntimeException(e); } }
并集的计算
/** * 计算多个Key的并集并写入到新的Key * @param cacheKeyArray 求并集的Key * @param destinationKey 并集结果写入的KEY */ public static void union(String[] cacheKeyArray, String destinationKey) { try(Jedis jedis = new Jedis("127.0.0.1", 6379)) { long result = jedis.sunionstore(destinationKey, cacheKeyArray); System.out.println("cacheKeyArray 的并集的个数:" + result); } catch (Exception e) { throw new RuntimeException(e); } }
并集计算结果写入到指定文件
/** * 将计算的并集数据写入到指定文件 */ public static void writeUnionToFile() { File unionFile = new File(unionFileString); try(Jedis jedis = new Jedis("127.0.0.1", 6379)) { Set result = jedis.smembers(unionFileCacheKey); FileUtil.writeUtf8Lines(result, unionFile); } catch (Exception e) { throw new RuntimeException(e); } }
Redis命令说明
SDIFFSTORE destination key [key …]
举例说明:
key1 = {a,b,c,d}key2 = {c}key3 = {a,c,e}SDIFF key1 key2 key3 = {b,d}
SDIFFSTORE 命令的作用和SDIFF类似,不同的是它将结果保存到 destination 集合,而把结果集返回给客户端。
如果 destination 集合已经存在,则将其覆盖。
返回值
结果集中成员数量
SINTERSTORE destination key [key …]
举例说明:
key1 = {a,b,c,d}key2 = {c}key3 = {a,c,e}SINTER key1 key2 key3 = {c}
SINTERSTORE 命令与 SINTER 命令类似,不同的是它并不是直接返回结果集,而是将结果保存在 destination 集合中。
如果 destination 集合存在, 则会被覆盖。
返回值
结果集中成员数量
SUNIONSTORE destination key [key …]
举例说明:
key1 = {a,b,c,d}key2 = {c}key3 = {a,c,e}SUNION key1 key2 key3 = {a,b,c,d,e}
SUNIONSTORE 命令的功能类似于 SUNION,不同的是不反回结果集,而是存储在 destination 中。
如果 destination 已经存在,则被覆盖。
返回值
结果集中的成员数量Redis视频教学