- 921. Minimum Add to Make Parentheses Valid 使括号有效的最少添加
- 915. Partition Array into Disjoint Intervals 分割数组
- 932. Beautiful Array 漂亮数组
- 940. Distinct Subsequences II 不同的子序列 II
在使用SpringBoot后端开发中,我们如果需要对Redis进行增删查改,可以很方便的使用RedisTemplate或者StringRedisTemplate等对象进行操作。但是在大数据中,如果想要对Redis进行操作,就没有那么方便,特别当flink新一代流式计算框架兴起后,没有直接读取和写入Redis的连接源,不管是开始的时候从Redis中获取数据,还是在中间需要读取维度数据,或者最后将数据写入到Redis,都不方便。此时一个较为方便的工具类就能很方便的使用,能达到节省开发时间、减小开发难度等目的。
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<scala.binary.version>2.11</scala.binary.version>
<scala.version>2.11.8</scala.version>
<flink.binary.version>1.10</flink.binary.version>
<flink.version>1.10.0</flink.version>
<log4j.version>1.2.17</log4j.version>
<slf4j.version>1.7.21</slf4j.version>
<mysql.version>8.0.21</mysql.version>
<fastjson.version>2.0.20</fastjson.version>
<avro.version>1.11.0</avro.version>
<huaweicloud.dws.jdbc.version>8.1.0</huaweicloud.dws.jdbc.version>
<commons.beanutils.version>1.9.4</commons.beanutils.version>
<guava.version>29.0-jre</guava.version>
<okhttp.version>3.6.0</okhttp.version>
<springboot.version>2.3.3.RELEASE</springboot.version>
<hikari.cp.version>2.6.1</hikari.cp.version>
<avro.version>1.10.0</avro.version>
<jedis.version>4.2.0</jedis.version>
<commons.lang.version>3.10</commons.lang.version>
<huaweicloud.obs.version>3.21.4</huaweicloud.obs.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- flink相关jar包 -->
<!--flink流的核心包-->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<!--flink中的Table相关包-->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-api-java</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-api-java-bridge_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<!-- flink连接kafka-->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<!--flink的rocksdb包-->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-statebackend-rocksdb_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<!--MySQL驱动包 mysql8版本-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
<scope>provided</scope>
</dependency>
<!-- jdbc连接池包(使用JDBCTemplate) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>${springboot.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>${hikari.cp.version}</version>
<scope>provided</scope>
</dependency>
<!--redis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
<scope>provided</scope>
</dependency>
<!-- 华为云GaussDB的连接JDBC的Jar包 -->
<dependency>
<groupId>com.huaweicloud.dws</groupId>
<artifactId>huaweicloud-dws-jdbc</artifactId>
<version>${huaweicloud.dws.jdbc.version}</version>
<scope>provided</scope>
</dependency>
<!-- 日志打印的jar包 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<scope>provided</scope>
</dependency>
<!-- json解析包,fastjson包 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
<scope>provided</scope>
</dependency>
<!-- avro压缩包 -->
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>${avro.version}</version>
<scope>provided</scope>
</dependency>
<!--commons-beanutils 是 Apache 开源组织提供的用于操作 JAVA BEAN 的工具包。使用 commons-beanutils,我们可以很方便的对 bean 对象的属性进行操作-->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>${commons.beanutils.version}</version>
<scope>provided</scope>
</dependency>
<!--Guava 工程包含了若干被 Google 的 Java 项目广泛依赖的核心库,方便开发-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
<scope>provided</scope>
</dependency>
<!-- 共有的lang包 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons.lang.version}</version>
<scope>provided</scope>
</dependency>
<!-- http包 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
<scope>provided</scope>
</dependency>
<!-- 华为云连接OBS包 -->
<dependency>
<groupId>com.huaweicloud</groupId>
<artifactId>esdk-obs-java</artifactId>
<version>${huaweicloud.obs.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>com.google.code.findbugs:jsr305</exclude>
<exclude>org.slf4j:*</exclude>
<exclude>log4j:*</exclude>
<exclude>org.apache.hadoop:*</exclude>
</excludes>
</artifactSet>
<filters>
<filter>
<!-- Do not copy the signatures in the META-INF folder.
Otherwise, this might cause SecurityExceptions when using the JAR. -->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>*.properties</exclude>
<exclude>*.xml</exclude>
</excludes>
</filter>
</filters>
<transformers combine.children="append">
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
注意:下述代码中使用了自定义的ModelUtil工具类,该工具类的具体介绍可以参考博主的另一篇博文:Flink(60):Flink中通用ModelUtil工具类
注意:下述方法为静态工具类,在使用时,直接使用RedisMlUtil调用方法即可;而且因为是静态工具类,所以这个类的库固定了,只能访问这个一个库的数据,如果需要其他的Redis集群可以再创建类似工具类(一般一个公司的Redis集群不会很多,所以一般用来读取数据的工具类,使用静态的即可)。并且其中的连接池的大小、超时时间等参数已进行固定(该参数可以根据公司集群来调节,博主使用的集群用如下配置即可)。另外还有,该类是静态,所以在每台机器上只会创建一个对象,这样连接池等大小就需要配置的大一点。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import redis.clients.jedis.JedisPoolConfig;
import java.time.Duration;
/**
* @date: 2022/12/29
* @Author ddkk.com 弟弟快看,程序员编程资料站
* @desc: ml-redis集群工具类
*/
public class RedisMlUtil {
static Logger logger = LoggerFactory.getLogger(RedisMlUtil.class);
/**
* StringRedisTemplate对象
*/
private static StringRedisTemplate stringRedisTemplate;
/**
* 获取StringRedisTemplate对象
*
* @return StringRedisTemplate对象
*/
public static StringRedisTemplate getStringRedisTemplate() {
if (stringRedisTemplate == null) {
synchronized (RedisMlUtil.class) {
if (stringRedisTemplate == null) {
// 创建 Jedis连接池 配置对象
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(50);
jedisPoolConfig.setMaxIdle(50);
jedisPoolConfig.setMinIdle(5);
// 通过 Jedis连接池配置 创建 jedis客户端 配置对象
JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfigurationBuilder = JedisClientConfiguration.builder();
jedisClientConfigurationBuilder.connectTimeout(Duration.ofMillis(3000));
jedisClientConfigurationBuilder.usePooling().poolConfig(jedisPoolConfig);
JedisClientConfiguration jedisClientConfiguration = jedisClientConfigurationBuilder.build();
// 创建 redis 配置对象
RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration();
redisConfiguration.setHostName(ModelUtil.getConfigValue("redis.ml.hostname"));
redisConfiguration.setPort(Integer.parseInt(ModelUtil.getConfigValue("redis.ml.port")));
redisConfiguration.setPassword(RedisPassword.of(ModelUtil.getConfigValue("redis.ml.password")));
redisConfiguration.setDatabase(Integer.parseInt(ModelUtil.getConfigValue("redis.ml.database")));
// 通过 jedis客户端配置对象 和 redis配置对象 创建Jedis连接工厂
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisConfiguration, jedisClientConfiguration);
// 通过 Jedis连接工厂 创建 redisTemplate
stringRedisTemplate = new StringRedisTemplate(jedisConnectionFactory);
logger.info(
"##### 创建ml-redis集群客户端StringRedisTemplate对象成功,其中最大连接数为:{},空闲连接数为:{},连接地址为:{}",
50,
5,
ModelUtil.getConfigValue("redis.ml.hostname")
);
}
}
}
return stringRedisTemplate;
}
/**
* 通过传入的key获取对应的value值
*
* @param key 键
* @return 值
*/
public static String getValue(String key) {
return RedisMlUtil.getStringRedisTemplate().opsForValue().get(key);
}
}
注意:下述方法为静态工具类,在使用时,直接使用RedisMlUtil调用方法即可;而且因为是静态工具类,所以这个类的库固定了,只能访问这个一个库的数据,如果需要其他的Redis集群可以再创建类似工具类(一般一个公司的Redis集群不会很多,所以一般用来读取数据的工具类,使用静态的即可)。并且其中的连接池的大小、超时时间等参数已进行固定(该参数可以根据公司集群来调节,博主使用的集群用如下配置即可)。另外还有,该类是静态,所以在每台机器上只会创建一个对象,这样连接池等大小就需要配置的大一点。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* @date: 2022/12/29
* @Author ddkk.com 弟弟快看,程序员编程资料站
* @desc: ml-redis集群工具类
*/
public class RedisMlUtil {
static Logger logger = LoggerFactory.getLogger(RedisMlUtil.class);
/**
* JedisPool对象
*/
private static JedisPool jedisPool;
/**
* 获取JedisPool对象
*
* @return JedisPool对象
*/
public static JedisPool getJedisPool() {
if (jedisPool == null) {
synchronized (RedisMlUtil.class) {
if (jedisPool == null) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(50);
poolConfig.setMaxIdle(50);
poolConfig.setMinIdle(5);
jedisPool = new JedisPool(
poolConfig,
ModelUtil.getConfigValue("redis.ml.hostname"),
Integer.parseInt(ModelUtil.getConfigValue("redis.ml.port")),
3000,
ModelUtil.getConfigValue("redis.ml.password")
);
logger.info(
"根据传入的参数创建redis连接池jedisPool对象成功,使用的host为:{},使用的port为:{},最大连接数为{},最大空闲连接数为{},最小空闲连接数为:{},连接超时时间为(毫秒):{}",
ModelUtil.getConfigValue("redis.ml.hostname"),
Integer.parseInt(ModelUtil.getConfigValue("redis.ml.port")),
50,
50,
5,
3000
);
}
}
}
return jedisPool;
}
/**
* 获取对应的 Jedis
* 注意:该jedis对象是从连接池中返回,使用完之后需要关闭
*
* @param index redis对应的索引
* @return Jedis
*/
public static Jedis getJedis(int index) {
Jedis jedis = getJedisPool().getResource();
jedis.select(index);
return jedis;
}
/**
* 通过传入的key获取对应的value值
*
* @param key 键
* @return 值
*/
public static String getValue(int index, String key) {
Jedis jedis = getJedis(index);
String value = jedis.get(key);
jedis.close();
return value;
}
}
注意:该工具类没有使用静态,所以在每次使用的时候,需要在open方法中创建该工具类对象,然后在process方法中使用该工具类中的方法即可。此工具类即可以用于维度等数据读取,又能用于将结果数据写入,并且每次创建工具类的时候,可以指定不同的Redis集群和不同的参数。同样,因为每次使用时都创建该类的对象,这样Flink程序中每一个并发,所以在使用时需要注意连接池等参数不要配置的太大。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* @date: 2022/12/6
* @Author ddkk.com 弟弟快看,程序员编程资料站
* @desc: RedisUtil
*/
public class RedisUtil {
static Logger logger = LoggerFactory.getLogger(RedisUtil.class);
/**
* jedis连接池
*/
private JedisPool jedisPool;
/**
* 通过传入的参数创建RedisUtil对象
*
* @param host redis的host
* @param port redis的端口
* @param password redis的password
*/
public RedisUtil(String host, int port, String password) {
initJedisPool(host, port, password, 2, 2, 1, 3000);
}
/**
* 通过传入的参数创建RedisUtil对象
*
* @param host redis的host
* @param port redis的端口
* @param password redis的password
* @param maxTotal 连接池中最大连接数
* @param maxIdle 连接池中最大空闲连接数
* @param minIdle 连接池中最小空闲连接数
* @param timeout 连接Redis超时时间
*/
public RedisUtil(String host, int port, String password, int maxTotal, int maxIdle, int minIdle, int timeout) {
initJedisPool(host, port, password, maxTotal, maxIdle, minIdle, timeout);
}
/**
* 初始化Jedis对象
*
* @param host redis的host
* @param port redis的端口
* @param password redis的password
* @param maxTotal 连接池中最大连接数
* @param maxIdle 连接池中最大空闲连接数
* @param minIdle 连接池中最小空闲连接数
* @param timeout 连接Redis超时时间
*/
public void initJedisPool(String host, int port, String password, int maxTotal, int maxIdle, int minIdle, int timeout) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(maxTotal);
poolConfig.setMaxIdle(maxIdle);
poolConfig.setMinIdle(minIdle);
jedisPool = new JedisPool(
poolConfig,
host,
port,
timeout,
password
);
logger.info(
"根据传入的参数创建redis连接池jedisPool对象成功,使用的host为:{},使用的port为:{},最大连接数为{},最大空闲连接数为{},最小空闲连接数为:{},连接超时时间为(毫秒):{}",
host,
port,
maxTotal,
maxIdle,
minIdle,
timeout
);
}
/**
* 获取对应的 Jedis
* 注意:该jedis对象是从连接池中返回,使用完之后需要关闭
*
* @param index redis对应的索引
* @return Jedis
*/
public Jedis getJedis(int index) {
Jedis jedis = jedisPool.getResource();
jedis.select(index);
return jedis;
}
/**
* 根据传入的数据库索引和key获取对应的值
* 注意:如果该key不存在,就返回 'nil',如果存储在key的值不是字符串,则返回错误
*
* @param index redis的索引
* @param key redis的key
* @return value
*/
public String getValue(int index, String key) {
Jedis jedis = getJedis(index);
String value = jedis.get(key);
jedis.close();
return value;
}
}
在Flink作业中如何使用上述工具类,可以参考博主的另一篇MySQL工具类文章:Flink(62):Flink中通用MySQLUtil工具类,使用基本相似,这里就不再过多描述了。
最近做一个项目,由于是在别人框架里开发app,导致了很多限制,其中一个就是不能直接引用webservice 。 我们都知道,调用webserivice 最简单的方法就是在 "引用"
这是SDL2代码的一部分 SDL主函数 int main(int argc,char *argv[]) { ... ... bool quit=false; S
c 中的函数: PHPAPI char *php_pcre_replace(char *regex, int regex_len, ch
我有以下映射: public class SecurityMap : ClassMap { public SecurityMap() {
我在vue-lic3中使用了SCSS,但是有一个奇怪的错误,使用/ deep /会报告错误,我不想看到它。 代码运行环境 vue-cli3 + vant + scss 的CSS /deep/ .van
我在深入阅读 C# 时遇到了这个我能理解的内容: 当它被限制为引用类型时,执行的比较类型完全取决于类型参数被限制为什么。 但是不能理解这个: 如果进一步限制派生自重载 == 和 != 运算符的特定类型
Closed. This question is opinion-based。它当前不接受答案。 想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。 3年前关闭。
有人可以详细介绍关于自赋值的运算符重载中的 *this 和 const 例如: Class& Class::operator=(const Class& other) { a = other.
在向树中插入新节点时,如何填充闭包表的深度/长度列? ancestor 和 descendant 中的值是来自另一个表的 ID,表示要以树结构排列的页面。 关闭表: ancestor desce
现在我正在阅读“深入了解 C#”。缺少的一件事是完成一章后我可以解决的一系列问题。那会帮助我理解我刚刚学到的概念。 哪里可以找到适合 C#3.0 的问题集? 谢谢 最佳答案 你可以试试LINQ 101
TypeScript 给 JavaScript 扩展了类型的语法,我们可以给变量加上类型,在编译期间会做类型检查,配合编辑器还能做更准确的智能提示。此外,TypeScript 还支持了高级类型用
是否有一个单行代码来获取生成器并生成该生成器中的所有元素?例如: def Yearly(year): yield YEARLY_HEADER for month in range(1, 13)
所以我阅读了一些与“什么是方法组”相关的 StackOverflow 问题以及其他互联网文章,它们在底线都说了同样的话——方法组是“一组重载方法” ". 但是,在阅读 Jon Skeet 的“C# 深
有什么方法可以从子组件中获取子组件吗? 想象一下以下组件树: 应用程序 问题 问题选项(包含复选框) 问题选项(包含复选框) 问题选项(包含复选框) 我想从 App 访问问题选项以选中所有复选框。 参
class_eval 和 instance_eval 在定义方法等情况下是完全可以预测的。我也理解类的实例和类的单例(又名特征类)之间的区别。 但是 我无法弄清楚以下唯一的事情:比方说,出于某些策略目
我想出了如何将符号 rwx 部分读取/转换为 421 个八进制部分,这非常简单。但是当涉及到特殊字符时,我感到非常困惑。我们知道 -r-xr---wx 转换为 0543,但 -r-sr---wt 或
我怀疑我系统的 Java 版本有问题。某些应用程序出现段错误或内存不足或存在链接错误。如果我从源代码安装了 JDK,我会做类似“make test”的事情,看看哪些测试失败了。但是,看起来从源代码构建
如何克隆一个 repo(使用 libgit2 ) 我想做什么git clone确实,但有 libgit2 .我可能要问的是什么 git clone确实很深入。 这是我目前正在做的: 初始化一个repo
00、头痛的JS闭包、词法作用域? 被JavaScript的闭包、上下文、嵌套函数、this搞得很头痛,这语言设计的,感觉比较混乱,先勉强理解总结一下😂😂😂.
我开始玩 lubridate R 中的包。我注意到 now(tzone="EST")计算为: [1] "2015-08-25 13:01:08 EST" 而 now(tzone="PST")导致警告:
我是一名优秀的程序员,十分优秀!