1. 在window上安装Redis
1. 下载Redis
- Github下载地址:Releases · microsoftarchive/redis · GitHub
2. 解压到某个目录下,我的在c:/apps/redis
3. 启动redis server。
C:\apps\redis>redis-server redis.windows.conf
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 3.0.504 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 39100
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
[39100] 22 May 14:48:13.225 # Server started, Redis version 3.0.504
[39100] 22 May 14:48:13.229 * The server is now ready to accept connections on port 6379
4. 打开另外命令窗口启动Redis command
命令是redis-cli.exe.
set name hello 是保持一个名字是name,值是hello的数据
get name: 是取出name的值
C:\apps\redis>redis-cli.exe
127.0.0.1:6379> set name hello
OK
127.0.0.1:6379> get name
"hello"
127.0.0.1:6379> get name
keys *: 取出所有的取出说有的key.
127.0.0.1:6379> keys *
1) "Student:liu2"
2) "Student:liu5"
3) "Student"
4) "Student:liu3"
5) "name"
用hmset 保存数据,用hget取数据
redis> HMSET myhash field1 "Hello" field2 "World"
"OK"
redis> HGET myhash field1
"Hello"
redis> HGET myhash field2
"World"
用hmset保持数据。key是application
HMSET application sample.property.name1 "somevalue" sample.property.name2 "anothervalue"
用hgetall 去application的数据
127.0.0.1:6379> hgetall application
1) "sample.property.name1"
2) "somevalue"
3) "sample.property.name2"
4) "anothervalue"
127.0.0.1:6379> hget application sample.property.name1
"somevalue"
127.0.0.1:6379> hget application sample.property.name2
"anothervalue"
刪除某一個key
127.0.0.1:6379> del certainkey
(integer) 1
按某种规则删除一批数据
KEYS "prefix:*" | xargs DEL
2. Java spring代码测试Redis
在pom.xml加maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.10</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<type>jar</type>
</dependency>
</dependencies>
创建Configuration
@Configuration
public class RedisConfiguration {
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConFactory
= new JedisConnectionFactory();
jedisConFactory.setHostName("localhost");
jedisConFactory.setPort(6379);
return jedisConFactory;
}
}
创建Student 类
@RedisHash("Student")
public class Student implements Serializable {
public enum Gender {
MALE, FEMALE
}
private String id;
private String name;
private Gender gender;
private int grade;
// ...
}
创建Redis respository
@Repository
public interface StudentRepository extends CrudRepository<Student, String> {}
创建StudentDataService
@Service
public class StudentDataService {
@Autowired
private StudentRepository studentRepository;
public Student saveStudent(String id) {
Student student = new Student(
id, "John Doe", Student.Gender.MALE, 1);
student = studentRepository.save(student);
return student;
}
public Student getStudent(String id) {
Student retrievedStudent =
studentRepository.findById(id).get();
return retrievedStudent;
}
public Student updateStudent(Student student) {
Student dbStduent = this.getStudent(student.getId());
dbStduent.setName(student.getName());
dbStduent = studentRepository.save(dbStduent);
return dbStduent;
}
public void deleteStudent(Student student) {
studentRepository.deleteById(student.getId());
}
public List<Student> getAllStudents() {
List<Student> students = new ArrayList<>();
studentRepository.findAll().forEach(students::add);
return students;
}
}
最后创建StudentController用于测试
@RestController
@RequestMapping("/student")
public class StudentContoller {
@Autowired
private StudentDataService studentDataService;
@RequestMapping("/save/{id}")
public String saveStudent(@PathVariable("id") String id) {
//"Eng2015001"
Student student = studentDataService.saveStudent(id);
return student.toString();
}
@RequestMapping("/get/{id}")
public String getStudent(@PathVariable("id") String id) {
Student student = studentDataService.getStudent(id);
return student.toString();
}
@RequestMapping("/delete/{id}")
public String deleteStudent(@PathVariable("id")String id) {
Student student = new Student();
student.setId(id);
studentDataService.deleteStudent(student);
return "success";
}
@RequestMapping("/update/{id}")
public String updateStudent(@PathVariable("id") String id) {
Student student = studentDataService.getStudent(id);
student.setName("updated1");
student = studentDataService.updateStudent(student);
return student.toString();
}
@RequestMapping("/getAll")
public String getAllStudents() {
List<Student> students= studentDataService.getAllStudents();
return students.toString();
}
}
3. redis的Keyspace Notifications实现定时任务队列
修改 redis.conf 或 redis.windows.conf 如果你用的是window版本的话
notify-keyspace-events Ex // 打开此配置,其中Ex表示键事件通知里面的key过期事件,每当有过期键被删除时,会发送通知
当 notify-keyspace-events
选项的参数为空字符串时,功能关闭。 默认是关闭
编写监听器
@Component
public class TaskTimeOutListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] pattern) {
String body = new String(message.getBody());
String channel = new String(message.getChannel());
System.out.println("Received task timeout event: "+body+" for key: " + channel);
String expiredKey = channel.split(":")[1];
//implemented logic to discard task
}
}
配置RedisMessageListenerContainer监听容器
@Configuration
public class RedisJmsConfiguration {
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(
RedisConnectionFactory connectionFactory,
TaskTimeOutListener taskTimeoutListener) {
System.out.println("===RedisMessageListenerContainer===" + taskTimeoutListener);
RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
listenerContainer.setConnectionFactory(connectionFactory);
ChannelTopic channelTopic = new ChannelTopic("__keyevent@0__:expired");
listenerContainer.addMessageListener(taskTimeoutListener, channelTopic);
listenerContainer.setErrorHandler(
e -> System.out.println("Error in redisMessageListenerContainer" + e.getMessage()));
return listenerContainer;
}
}
启动你的spring-boot项目
然后,在客户端创建一个key并且设置它的超时时间
set myname chhliu
expire myname 2
或者如下:
set myname chhliu px 2000
2秒后你就会发现下面的日志
Received task timeout event: {} for key: {}myname__keyevent@0__:expired
注意:
1、上面的_keyevent@0_:expired是key过期事件对应的topic,服务端会将过期事件推送到该topic中,然后客户端监听这个topic。
2、key过期事件推送到topic中的内容只有key,而无value,因为一旦过期,value就不存在了。
参考资料