redis-patterns by diego-tobalina/vibe-coding
npx skills add https://github.com/diego-tobalina/vibe-coding --skill redis-patterns@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1))
.disableCachingNullValues()
.serializeValuesWith(
SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(factory)
.cacheDefaults(config)
.withCacheConfiguration("users",
config.entryTtl(Duration.ofMinutes(30)))
.withCacheConfiguration("sessions",
config.entryTtl(Duration.ofHours(24)))
.build();
}
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
@Service
@RequiredArgsConstructor
public class UserService {
@Cacheable(value = "users", key = "#id")
public UserDto findById(UUID id) {
return userRepository.findById(id)
.map(userMapper::toDto)
.orElseThrow(() -> new UserNotFoundException(id));
}
@CachePut(value = "users", key = "#result.id")
@Transactional
public UserDto update(UUID id, UserUpdateDto dto) {
// 更新逻辑
}
@CacheEvict(value = "users", key = "#id")
@Transactional
public void delete(UUID id) {
userRepository.deleteById(id);
}
@CacheEvict(value = "users", allEntries = true)
public void clearAllCache() {
log.info("Clearing all user cache");
}
}
@Service
@RequiredArgsConstructor
public class RedisDataService {
private final RedisTemplate<String, Object> redisTemplate;
// String (简单缓存)
public void cacheValue(String key, Object value, Duration ttl) {
redisTemplate.opsForValue().set(key, value, ttl);
}
public Object getValue(String key) {
return redisTemplate.opsForValue().get(key);
}
// List (队列)
public void enqueue(String queue, Object item) {
redisTemplate.opsForList().leftPush(queue, item);
}
public Object dequeue(String queue) {
return redisTemplate.opsForList().rightPop(queue);
}
// Set (唯一项)
public void addToSet(String key, Object... values) {
redisTemplate.opsForSet().add(key, values);
}
public Set<Object> getSetMembers(String key) {
return redisTemplate.opsForSet().members(key);
}
// Hash (对象字段)
public void setHashField(String key, String field, Object value) {
redisTemplate.opsForHash().put(key, field, value);
}
public Map<Object, Object> getHash(String key) {
return redisTemplate.opsForHash().entries(key);
}
// Sorted Set (排行榜)
public void addToLeaderboard(String key, String member, double score) {
redisTemplate.opsForZSet().add(key, member, score);
}
public Set<Object> getTopN(String key, int n) {
return redisTemplate.opsForZSet().reverseRange(key, 0, n - 1);
}
}
import Redis from 'ioredis';
const redis = new Redis({
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT || '6379'),
password: process.env.REDIS_PASSWORD,
retryStrategy: (times) => Math.min(times * 50, 2000),
});
// 缓存旁路模式
async function getUser(id: string): Promise<User | null> {
const cached = await redis.get(`user:${id}`);
if (cached) return JSON.parse(cached);
const user = await db.findUser(id);
if (user) {
await redis.setex(`user:${id}`, 3600, JSON.stringify(user));
}
return user;
}
// 分布式锁
async function acquireLock(key: string, ttlMs: number): Promise<boolean> {
const result = await redis.set(`lock:${key}`, '1', 'PX', ttlMs, 'NX');
return result === 'OK';
}
async function releaseLock(key: string): Promise<void> {
await redis.del(`lock:${key}`);
}
// 速率限制
async function checkRateLimit(userId: string, limit: number, windowSec: number): Promise<boolean> {
const key = `ratelimit:${userId}`;
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, windowSec);
}
return current <= limit;
}
| 模式 | 数据结构 | 使用场景 |
|---|---|---|
| 缓存 | String | 带 TTL 的对象缓存 |
| 会话 | Hash | 用户会话数据 |
| 队列 | List | 作业处理 |
| 唯一项 | Set | 标签、关注者 |
| 排行榜 | Sorted Set | 排名、分数 |
| 速率限制 | String + INCR | API 限流 |
| 发布/订阅 | Channels | 实时消息传递 |
INFO memory 监控内存使用情况SCAN 而非 KEYS每周安装数
1
代码仓库
GitHub 星标数
1
首次出现
1 天前
安全审计
安装于
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1))
.disableCachingNullValues()
.serializeValuesWith(
SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(factory)
.cacheDefaults(config)
.withCacheConfiguration("users",
config.entryTtl(Duration.ofMinutes(30)))
.withCacheConfiguration("sessions",
config.entryTtl(Duration.ofHours(24)))
.build();
}
}
@Service
@RequiredArgsConstructor
public class UserService {
@Cacheable(value = "users", key = "#id")
public UserDto findById(UUID id) {
return userRepository.findById(id)
.map(userMapper::toDto)
.orElseThrow(() -> new UserNotFoundException(id));
}
@CachePut(value = "users", key = "#result.id")
@Transactional
public UserDto update(UUID id, UserUpdateDto dto) {
// update logic
}
@CacheEvict(value = "users", key = "#id")
@Transactional
public void delete(UUID id) {
userRepository.deleteById(id);
}
@CacheEvict(value = "users", allEntries = true)
public void clearAllCache() {
log.info("Clearing all user cache");
}
}
@Service
@RequiredArgsConstructor
public class RedisDataService {
private final RedisTemplate<String, Object> redisTemplate;
// String (simple cache)
public void cacheValue(String key, Object value, Duration ttl) {
redisTemplate.opsForValue().set(key, value, ttl);
}
public Object getValue(String key) {
return redisTemplate.opsForValue().get(key);
}
// List (queue)
public void enqueue(String queue, Object item) {
redisTemplate.opsForList().leftPush(queue, item);
}
public Object dequeue(String queue) {
return redisTemplate.opsForList().rightPop(queue);
}
// Set (unique items)
public void addToSet(String key, Object... values) {
redisTemplate.opsForSet().add(key, values);
}
public Set<Object> getSetMembers(String key) {
return redisTemplate.opsForSet().members(key);
}
// Hash (object fields)
public void setHashField(String key, String field, Object value) {
redisTemplate.opsForHash().put(key, field, value);
}
public Map<Object, Object> getHash(String key) {
return redisTemplate.opsForHash().entries(key);
}
// Sorted Set (leaderboard)
public void addToLeaderboard(String key, String member, double score) {
redisTemplate.opsForZSet().add(key, member, score);
}
public Set<Object> getTopN(String key, int n) {
return redisTemplate.opsForZSet().reverseRange(key, 0, n - 1);
}
}
import Redis from 'ioredis';
const redis = new Redis({
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT || '6379'),
password: process.env.REDIS_PASSWORD,
retryStrategy: (times) => Math.min(times * 50, 2000),
});
// Cache-aside pattern
async function getUser(id: string): Promise<User | null> {
const cached = await redis.get(`user:${id}`);
if (cached) return JSON.parse(cached);
const user = await db.findUser(id);
if (user) {
await redis.setex(`user:${id}`, 3600, JSON.stringify(user));
}
return user;
}
// Distributed lock
async function acquireLock(key: string, ttlMs: number): Promise<boolean> {
const result = await redis.set(`lock:${key}`, '1', 'PX', ttlMs, 'NX');
return result === 'OK';
}
async function releaseLock(key: string): Promise<void> {
await redis.del(`lock:${key}`);
}
// Rate limiting
async function checkRateLimit(userId: string, limit: number, windowSec: number): Promise<boolean> {
const key = `ratelimit:${userId}`;
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, windowSec);
}
return current <= limit;
}
| Pattern | Data Structure | Use Case |
|---|---|---|
| Cache | String | Object caching with TTL |
| Session | Hash | User session data |
| Queue | List | Job processing |
| Unique Items | Set | Tags, followers |
| Leaderboard | Sorted Set | Rankings, scores |
| Rate Limit | String + INCR | API throttling |
| Pub/Sub | Channels | Real-time messaging |
INFO memorySCAN instead of KEYS in productionWeekly Installs
1
Repository
GitHub Stars
1
First Seen
1 day ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
GSAP 框架集成指南:Vue、Svelte 等框架中 GSAP 动画最佳实践
2,300 周安装