赞
踩
Redis数据库基础知识,类型知识点梳理~
Redis是一种基于内存的开源键值对存储系统,支持多种数据结构类型。
String(字符串)
SET key value
:设置键值。GET key
:获取键值。INCR key
/ DECR key
:对值进行原子递增/递减操作。APPEND key value
:追加字符串。List(列表)
LPUSH key value
/ RPUSH key value
:从左/右插入元素。LPOP key
/ RPOP key
:从左/右弹出元素。LRANGE key start stop
:获取指定范围内的元素。Set(集合)
SADD key member
:添加元素。SREM key member
:删除元素。SMEMBERS key
:获取所有元素。SINTER key1 key2
:求交集。SUNION key1 key2
:求并集。SDIFF key1 key2
:求差集。Sorted Set(有序集合)
ZADD key score member
:添加元素及其分数。ZRANGE key start stop [WITHSCORES]
:按排名获取元素。ZREM key member
:删除元素。ZRANK key member
:获取元素的排名。Hash(哈希表)
HSET key field value
:设置字段的值。HGET key field
:获取字段的值。HGETALL key
:获取所有字段和值。HDEL key field
:删除字段。HyperLogLog
PFADD key element
:添加元素。PFCOUNT key
:返回基数估算结果。Bitmap
SETBIT key offset value
:设置位的值。GETBIT key offset
:获取位的值。BITCOUNT key [start end]
:统计特定位范围内1的数量。Geospatial(地理位置)
GEOADD key longitude latitude member
:添加地理位置。GEORADIUS key longitude latitude radius unit
:查询指定半径内的成员。GEODIST key member1 member2 unit
:计算两个成员之间的距离。Streams
XADD key * field value [field value ...]
:添加日志条目。XRANGE key start end
:按范围获取条目。XREAD COUNT count STREAMS key ID
:读取新条目。XGROUP CREATE key groupname id
:创建消费组。使用分布式锁时,要考虑锁的超时时间、锁的可重入性、锁的安全性等方面的问题,以确保系统的正确性和性能。
Redis中的分布式锁类型:
SETNX
命令来实现锁的获取,当某个客户端成功地将一个特定的键设置为锁时,其他客户端无法再设置该键,从而实现分布式锁的效果。Redlock算法
是由Redis的作者提出的一种分布式锁算法,它通过在多个独立的Redis实例上加锁来实现分布式锁。Redisson
实现的分布式锁利用了Redis的特性,并且内置了看门狗机制,并且Redisson内部已经处理好了看门狗机制。当你获取到锁后,Redisson会启动一个后台线程,周期性地延长锁的过期时间(每隔10秒),确保锁在持有期间不会因为过期而被自动释放。这个机制有效地防止了因意外长时间持锁导致的死锁问题。SET key value PX milliseconds NX
命令来实现。DEL key
命令删除锁的键。(1)引入Redisson的依赖。
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.16.3</version>
</dependency>
(2)配置Redisson客户端。
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
public class RedissonConfig {
public static RedissonClient createClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
return Redisson.create(config);
}
}
(3)通过Redisson客户端来获取和释放分布式锁。
import org.redisson.api.RLock; import org.redisson.api.RedissonClient; public class DistributedLockExample { public static void main(String[] args) { RedissonClient redissonClient = RedissonConfig.createClient(); // 获取名为 "myLock" 的锁 RLock lock = redissonClient.getLock("myLock"); try { // 尝试获取锁,等待时间为100秒,如果获取成功,则持有锁10秒 if (lock.tryLock(100, 10, TimeUnit.SECONDS)) { try { // 锁获取成功,执行需要加锁的业务逻辑 System.out.println("锁定成功,执行业务逻辑"); } finally { // 释放锁 lock.unlock(); } } else { System.out.println("未能获取到锁"); } } catch (InterruptedException e) { e.printStackTrace(); } finally { redissonClient.shutdown(); } } }
使用分布式锁场景:
Redis中的事务是一组命令的原子性操作,可以保证这组命令要么全部执行成功,要么全部失败。Redis事务使用
MULTI、EXEC、DISCARD和WATCH
等命令进行控制。
Redis事务命令类型:
Redis事务使用场景:
WATCH
命令和事务结合,可以实现乐观锁机制。在操作某个键之前,先通过WATCH
命令监视该键,如果在执行事务期间该键的值被修改,则事务执行失败。可以利用这个特性实现乐观锁来保证并发操作的一致性。BRPOP
命令可以实现简单的队列功能。多个客户端可以并发地将任务推入队列,然后通过事务的方式一次性取出多个任务进行处理。Redis事物使用Demo:
import redis.clients.jedis.Jedis; import redis.clients.jedis.Response; import redis.clients.jedis.Transaction; public class RedisTransactionExample { public static void main(String[] args) { // 使用Jedis库连接Redis服务器 Jedis jedis = new Jedis("localhost", 6379); // 开启事务 Transaction transaction = jedis.multi(); // 将多个命令添加到事务中 transaction.set("key1", "value1"); transaction.set("key2", "value2"); // 执行事务,并返回执行结果 Response<String> response1 = transaction.get("key1"); Response<String> response2 = transaction.get("key2"); // 执行事务 // 在事务中,命令并不会立即执行,而是放入队列中等待exec()命令执行 transaction.exec(); // 获取执行结果 String value1 = response1.get(); String value2 = response2.get(); System.out.println("Value of key1: " + value1); System.out.println("Value of key2: " + value2); // 关闭连接 jedis.close(); } }
**ps:**Redis事务并不是严格的ACID事务,它没有提供隔离级别和回滚日志等特性。在Redis事务中,如果某个命令执行失败,后续的命令仍然会继续执行,而不会回滚到事务开始之前的状态,对于强一致性要求较高的场景,Redis事务可能不适用。
Redis事务适用于对数据一致性要求较低但需要确保操作顺序的场景。对于更复杂的事务管理和更高的数据一致性要求,可能需要考虑使用关系型数据库或其他解决方案。
import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction; public class RedisTransactionExample { public static void main(String[] args) { Jedis jedis = new Jedis("localhost"); // 开启事务 Transaction transaction = jedis.multi(); try { // 将多个命令打包到一个事务中 transaction.incr("counter"); transaction.rpush("queue", "message1"); transaction.set("key1", "value1"); // 执行事务 transaction.exec(); } catch (Exception e) { e.printStackTrace(); // 处理事务执行失败的情况,放弃事务 transaction.discard(); } finally { jedis.close(); } } }
import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction; public class RedisTransactionExample { public static void main(String[] args) { Jedis jedis = new Jedis("localhost"); // 开启事务 Transaction transaction = jedis.multi(); try { // 将多个命令按顺序打包到一个事务中 transaction.set("key1", "value1"); transaction.set("key2", "value2"); transaction.incr("counter"); // 执行事务 transaction.exec(); } catch (Exception e) { e.printStackTrace(); // 处理事务执行失败的情况,放弃事务 transaction.discard(); } finally { jedis.close(); } } }
import redis.clients.jedis.Jedis; import redis.clients.jedis.Transaction; public class RedisTransactionExample { public static void main(String[] args) { Jedis jedis = new Jedis("localhost"); // 开启事务 Transaction transaction = jedis.multi(); try { // 将多个命令打包到一个事务中 transaction.set("key1", "value1"); transaction.incr("counter"); // 故意引入错误的命令(例如对不存在的哈希字段进行递增) transaction.hincrBy("nonexistent_hash", "field", 1); // 执行事务 transaction.exec(); } catch (Exception e) { e.printStackTrace(); // 处理事务执行失败的情况,放弃事务 transaction.discard(); } finally { jedis.close(); } } }
无论世界如何纷扰,心中有梦,便有了方向
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。