2024-09-03

Redis 7 安装

对于不同的操作系统,安装Redis 7的方法可能会有所不同。以下是在Linux系统上安装Redis 7的步骤:

  1. 使用命令行下载并解压Redis 7的源代码:

    
    
    
    wget http://download.redis.io/releases/redis-7.0.0.tar.gz
    tar xzf redis-7.0.0.tar.gz
    cd redis-7.0.0
  2. 编译Redis:

    
    
    
    make
  3. 安装Redis(可选):

    
    
    
    sudo make install

Redis 7 配置

Redis的配置文件是redis.conf,你可以根据需要进行修改。例如,你可以修改默认的监听端口或者设置持久化选项。

Redis 7 卸载

如果你需要卸载Redis 7,你可以按照以下步骤操作:

  1. 停止Redis服务。
  2. 删除安装目录下的Redis文件。
  3. 删除配置文件和相关的日志文件。

使用可视化工具连接Redis

可以使用Redis Desktop Manager或其他可视化工具来连接并管理Redis数据库。以Redis Desktop Manager为例,步骤如下:

  1. 下载并安装Redis Desktop Manager。
  2. 打开软件,在界面上填写Redis服务器的IP地址、端口、密码等信息。
  3. 点击“连接”按钮,如果配置正确,你将能够看到Redis数据库中的数据并进行可视化操作。

请注意,具体的安装步骤和配置可能会根据不同的操作系统和可视化工具有所变化。

2024-09-03

在Redis中,如果你想关闭手动触发的SAVEBGSAVE命令,可以通过配置文件或者运行时通过命令来实现。

  1. 通过配置文件关闭手动SAVE

    在Redis配置文件中,找到以下行:

    
    
    
    save <seconds> <changes>

    将其注释掉或删除,这样Redis就不会在指定的时间内自动执行SAVE操作。

  2. 通过Redis命令关闭手动SAVE

    你可以在Redis CLI中执行以下命令来禁用手动SAVE

    
    
    
    config set save ""

    这条命令会设置Redis的保存策略为空,这样就不会自动执行SAVE操作。

  3. 关闭BGSAVE

    如果你也想关闭BGSAVE,可以使用类似的方法。在配置文件中找到以下行:

    
    
    
    rdbchecksum yes

    将其改为:

    
    
    
    rdbchecksum no

    这样Redis在执行BGSAVE时就不会进行校验和计算,从而减少性能开销。

请注意,关闭手动SAVEBGSAVE可能会影响你的数据持久化策略,因此请确保你有其他的自动持久化机制来代替它们,如RDB或AOF。

2024-09-03

Redis 主从复制和集群配置涉及多个方面,以下是基于 Redis 配置主从复制和创建 Redis Cluster 的简要步骤和示例配置:

主从复制配置:

  1. 在主节点的 redis.conf 文件中设置:



bind 0.0.0.0
port 6379
  1. 在从节点的 redis.conf 文件中设置:



bind 0.0.0.0
port 6380
slaveof <主节点IP> <主节点端口>

启动主节点和从节点的 Redis 服务。

Redis Cluster 配置:

  1. 在每个节点的 redis.conf 文件中设置:



bind 0.0.0.0
port 6379
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
  1. 启动所有节点的 Redis 服务。
  2. 使用 redis-cli 创建集群:



redis-cli --cluster create <节点IP1>:<端口1> <节点IP2>:<端口2> ... --cluster-replicas 1

其中,<节点IP1>:<端口1> 是你的 Redis 节点列表,--cluster-replicas 1 指定每个主节点的副本数。

以上步骤和配置是基于 Redis 的默认设置。根据实际部署环境,可能需要调整配置,例如设置密码、调整网络参数等。

2024-09-03

在Redis 7.x中,可以通过Redis Cluster Manager (RCM)来动态地对Redis集群进行扩容或缩容。以下是一个简化的例子,展示如何使用RCM来扩展集群的容量。

首先,确保你已经安装了Redis 7.x和RCM。

  1. 启动一个新的Redis节点,并将其加入到集群中:



redis-cli --cluster add-node new_node_ip:new_node_port existing_node_ip:existing_node_port
  1. 对新节点进行数据迁移:



redis-cli --cluster reshard new_node_ip:new_node_port

按照提示选择源节点和目标节点,以及需要迁移的键的数量。

  1. 重新分配hash slots:



redis-cli --cluster rebalance new_node_ip:new_node_port

按照提示确认开始重新分配。

对于缩容,步骤相似:

  1. 对于想要移除的节点,重新分配其slots到其他节点:



redis-cli --cluster rebalance existing_node_ip:existing_node_port
  1. 移除节点:



redis-cli --cluster del-node new_node_ip:new_node_port

注意:在实际操作中,应该在维护窗口和负载低峰时段执行这些操作,以避免对服务造成影响。

2024-09-03



from fastapi import FastAPI
from fastapi_utils.tasks import repeat_every_second
from celery import Celery
 
# 初始化FastAPI应用
app = FastAPI()
 
# 创建Celery实例
def create_celery_app(app: FastAPI):
    celery = Celery('fastapi_celery', broker='redis://localhost:6379/0', backend='redis://localhost:6379/0')
    celery.conf.update(
        result_expires=3600,
    )
    celery.conf.beat_schedule = {
        'add-every-second': {
            'task': 'fastapi_celery.tasks.add',
            'schedule': 1.0,
            'args': (1, 2)
        },
    }
    @celery.on_after_configure.connect
    def setup_periodic_tasks(sender, **kwargs):
        # 自定义定时任务
        pass
    return celery
 
# 创建Celery对象
celery_app = create_celery_app(app)
 
# 定义Celery任务
@celery_app.task
def add(x, y):
    return x + y
 
# 定义FastAPI路由
@app.get("/")
async def root():
    return {"message": "Hello World"}
 
# 启动FastAPI和Celery Worker
if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

这个代码示例展示了如何在FastAPI应用中集成Redis和Celery来实现异步任务和定时任务。首先,我们创建了一个Celery实例,指定了Redis作为消息代理和结果存储。然后,我们定义了一个定时任务“add-every-second”,它会每秒调用一个名为fastapi_celery.tasks.add的异步任务。最后,我们启动了FastAPI服务和Celery Worker。这个例子简洁明了,展示了如何将FastAPI与异步任务框架结合使用。

2024-09-03

在这一讲中,我们将会讨论Redis的发布/订阅(pub/sub)功能。这个功能让你可以建立一个消息发送者和接收者,发送者可以发布消息到一个频道,而接收者可以订阅一个或多个频道。当有消息发布到频道的时候,订阅这个频道的客户端会收到消息。

Redis的发布/订阅功能是一种消息通信模式,发布者(publisher)发布消息,订阅者(subscriber)接收消息。

在Python中,我们可以使用redis包来操作Redis的发布/订阅功能。

首先,我们需要创建一个Redis连接:




import redis
 
r = redis.Redis(host='localhost', port=6379, db=0)

然后,我们可以使用subscribe方法来订阅一个或者多个频道:




pubsub = r.pubsub()
pubsub.subscribe('channel-1')
pubsub.subscribe(**{'channel-2': callback})

在上面的代码中,我们订阅了名为'channel-1'的频道,并且我们还通过callback函数订阅了名为'channel-2'的频道。

接下来,我们可以使用publish方法来发布消息到一个频道:




r.publish('channel-1', 'Hello channel-1')
r.publish('channel-2', 'Hello channel-2')

在上面的代码中,我们发布了两条消息,一条到'channel-1',另一条到'channel-2'。

最后,我们可以在订阅的客户端使用parse_response方法来接收并处理消息:




for message in pubsub.listen():
    print(message)

在上面的代码中,我们在订阅的客户端接收并处理消息,当有消息发送到订阅的频道时,我们就会收到消息。

注意,pubsub.listen()方法是一个阻塞操作,它会持续等待并接收消息,直到调用pubsub.unsubscribe或者pubsub.unsubscribe_all方法退订所有频道。

总结一下,Redis的发布/订阅功能可以让我们在应用程序之间建立一个简单的消息通信。在Python中,我们可以使用redis包来操作Redis的发布/订阅功能。

2024-09-03



import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
 
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
 
@Component
public class CacheService {
 
    @Autowired
    private StringRedisTemplate redisTemplate;
 
    private LoadingCache<String, String> cache = CacheBuilder.newBuilder()
            .maximumSize(1000)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build(new CacheLoader<String, String>() {
                @Override
                public String load(String key) throws Exception {
                    // 缓存失效时,从Redis加载数据
                    return redisTemplate.opsForValue().get(key);
                }
            });
 
    public String get(String key) throws ExecutionException {
        // 尝试从Guava缓存获取数据
        String value = cache.get(key);
        if (value == null) {
            // 缓存未命中,可能发生缓存穿透、缓存击穿或缓存雪崩
            // 可以采取相应措施,如设置默认值、缓存空对象等
            // 这里简单返回null,实际应用中可以根据业务需求处理
            return null;
        }
        return value;
    }
 
    public void put(String key, String value) {
        // 数据更新时,同时更新Redis和Guava缓存
        redisTemplate.opsForValue().set(key, value);
        cache.put(key, value);
    }
 
    public void remove(String key) {
        // 删除缓存数据时,同时操作Redis和Guava缓存
        redisTemplate.delete(key);
        cache.invalidate(key);
    }
}

这个示例展示了如何在Spring Boot应用中使用Redis和Guava Cache来提供缓存服务。get方法首先尝试从Guava缓存中获取数据,如果缓存未命中,则从Redis加载数据。put方法更新缓存和Redis,remove方法删除缓存和Redis中的数据。在实际应用中,可以根据业务需求和缓存穿透、击穿、雪崩等问题的情况,适当地设置缓存的默认值、空对象或采用分布式锁等策略来避免这些问题。

2024-09-03

要监听Redis中Key值的变化,可以使用spring-data-redis中的RedisMessageListenerContainerMessageListener。以下是一个简单的例子:

  1. 添加依赖到你的pom.xml



<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  1. 配置RedisMessageListenerContainerMessageListenerAdapter



@Component
public class RedisKeyChangeListener {
 
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
 
    @Bean
    RedisMessageListenerContainer redisContainer() {
        final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(stringRedisTemplate.getConnectionFactory());
        container.addMessageListener(messageListenerAdapter(), topic());
        return container;
    }
 
    @Bean
    MessageListenerAdapter messageListenerAdapter() {
        return new MessageListenerAdapter(new RedisKeyChangeHandler());
    }
 
    @Bean
    ChannelTopic topic() {
        return new ChannelTopic("redisKeyChangeTopic");
    }
 
    @Component
    public static class RedisKeyChangeHandler {
        public void handleMessage(Message message, byte[] pattern) {
            // message.toString() 可以获取到Key的变化信息
            System.out.println("Received Redis message: " + message);
        }
    }
}
  1. 在Redis中发布消息的时候,确保使用PUBLISH命令发布到redisKeyChangeTopic



PUBLISH redisKeyChangeTopic "key1 has changed"

当Redis中的key值发生变化时,会自动触发RedisKeyChangeHandler中的handleMessage方法,并打印出变化信息。

注意:这个例子假设你已经有一个运行中的Redis服务器,并且spring.redis的配置已经在application.propertiesapplication.yml中设置好了。

2024-09-03

Redis Cluster是Redis提供的分布式解决方案,它通过分片(sharding)来进行数据管理,并提供高可用支持。

一、概述

Redis Cluster采用无中心结构,每个节点维护自己的slot状态,通过二者之间的gossip协议交换节点状态信息。

二、基本使用

  1. 启动Redis Cluster



redis-server /path/to/your/redis.conf --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000
  1. 创建Redis Cluster



redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1
  1. 使用Redis Cluster客户端



import redis
from rediscluster import RedisCluster
 
# 假设Redis Cluster的节点在本地的7000, 7001, 7002端口
startup_nodes = [
    {"host": "127.0.0.1", "port": "7000"},
    {"host": "127.0.0.1", "port": "7001"},
    {"host": "127.0.0.1", "port": "7002"}
]
 
# 连接Redis Cluster
rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)
 
# 使用Redis Cluster客户端操作
rc.set("foo", "bar")
print(rc.get("foo"))

三、运维注意事项

  1. 数据分布:Redis Cluster采用哈希槽(hash slot)来分配数据。
  2. 节点通信:节点之间通过gossip协议交换信息。
  3. 故障转移:当一个主节点不可用时,其从节点会自动升级为主节点。
  4. 扩容缩容:可以动态添加或删除节点。

四、注意事项

  • 确保Redis Cluster的每个节点的配置文件中的cluster配置正确。
  • 在生产环境中,应该使用奇数个主节点。
  • 在扩展或缩减集群时,应该先对配置文件进行相应修改,然后重启服务。
  • 客户端连接时,应该提供足够的startup nodes,以便能够发现整个cluster。
2024-09-03

Redis-son是一个Redis的Java客户端,它提供了一系列的注解和AOP的方式来简化开发者对Redis操作的编码。

以下是一个使用Redis-son的限流器的简单示例:




import com.redis.son.JedisSonicSession;
import com.redis.son.SonicEdits;
 
public class RedisRateLimiter {
    private JedisSonicSession session;
 
    public RedisRateLimiter(JedisSonicSession session) {
        this.session = session;
    }
 
    public boolean isAllowed(String userId, int maxRequests, int timeInterval) {
        String key = "rate_limiter:" + userId;
        // 使用SonicEdits的incr方法来递增键的值,并返回递增后的值
        long requests = session.sonicEdits().incr(key).ret(0L).get();
        // 如果递增后的值是1,说明这是第一次请求,直接返回true允许通过
        if (requests == 1) {
            return true;
        }
        // 如果递增后的值大于1,说明不是第一次请求,检查是否超过了限制
        if (requests > maxRequests) {
            // 如果超过了,则返回false不允许通过
            return false;
        }
        // 如果没有超过限制,则计算当前时间和最后一次请求的时间差
        long currentTime = System.currentTimeMillis() / 1000;
        long lastRequestTime = session.get(key + ":time").ret(0L).get();
        long elapsedTime = currentTime - lastRequestTime;
        // 如果经过的时间超过了设定的间隔,重置请求计数器
        if (elapsedTime > timeInterval) {
            session.set(key, 1);
            session.set(key + ":time", currentTime);
            return true;
        }
        // 否则返回false不允许通过
        return false;
    }
}

在这个例子中,我们创建了一个简单的本地限流器,它使用Redis的INCR命令来跟踪用户的请求数量,并且使用Redis的键的过期特性来重置请求计数器。这个限流器可以很容易地被集成到任何需要限流的应用程序中。