首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Redis 從入門到實戰:安裝配置、Jedis 操作、持久化機制與綜合案例

     編輯:Java 綜合教學

一、NoSQL 與 Redis 速覽

1.1 NoSQL 四大分類

類型代表產品特點
鍵值Redis, Voldemort, Oracle BDB高性能、簡單、適合緩存
列存儲Cassandra, HBase, Riak海量分布式存儲、列族組織
文檔MongoDB, CouchDB, SequoiaDB半結構化、JSON、支持嵌套查詢
圖形Neo4J, InfoGrid關係圖譜、社交網絡、推薦系統

1.2 Redis 定位

  • ANSI C 開發、BSD 協議、基於內存+可持久化的 Key-Value 存儲。
  • 數據結構豐富:String、Hash、List、Set、Sorted Set、Bitmap、HyperLogLog、Geospatial、Stream。
  • 單線程模型、IO 多路復用、高性能(10萬+ QPS)。

二、Windows 下 Redis 安裝與服務化

2.1 下載與解壓

2.2 註冊為 Windows 服務

# 管理員 CMD 執行
cd D:\Redis
redis-server --service-install redis.windows.conf --loglevel verbose
redis-server --service-start

2.3 批處理腳本管理多服務(含 Redis)

@echo off
:a
echo 請選擇操作:
echo 1 啟動 MSSQL    2 停止 MSSQL
echo 3 啟動 Oracle   4 停止 Oracle
echo 5 快速關機
echo 6 啟動 MySQL    7 停止 MySQL
echo 8 啟動 Redis    9 停止 Redis
set /p var1=請輸入指令 [1-9]:
if "%var1%"=="8" net start redis
if "%var1%"=="9" net stop redis
... 其他服務同理 ...
goto a

批處理運行效果

三、Jedis 客戶端實戰

3.1 Maven 依賴

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.3.1</version> <!-- 當前建議 4.x,兼容 Redis 6+ -->
</dependency>

依賴樹

3.2 基礎連接與 CRUD

public class HelloJedis {
    public static void main(String[] args) {
        // 1. 創建連接(生產環境請用連接池 JedisPool)
        try (Jedis jedis = new Jedis("127.0.0.1", 6379)) {
            // 2. String 操作
            jedis.set("message", "Hello Redis!");
            System.out.println(jedis.get("message"));

            // 3. Hash 操作
            jedis.hset("user:1", "name", "張三");
            jedis.hset("user:1", "age", "25");
            System.out.println(jedis.hgetAll("user:1"));

            // 4. List 操作
            jedis.lpush("tasks", "task1", "task2");
            System.out.println(jedis.lrange("tasks", 0, -1));

            // 5. 過期時間
            jedis.expire("message", 60); // 60秒後過期
        }
    }
}

運行結果

3.3 生產必備:JedisPool 配置

@Configuration
public class RedisConfig {
    @Bean
    public JedisPool jedisPool(@Value("${redis.host}") String host,
                               @Value("${redis.port}") int port) {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(50);
        config.setMaxIdle(20);
        config.setMinIdle(5);
        config.setTestOnBorrow(true);
        return new JedisPool(config, host, port, 3000);
    }
}

四、Redis 持久化機制深度解析

4.1 RDB(快照)

  • 觸發條件(默認配置):
    • 900秒內 ≥1 key 變化
    • 300秒內 ≥10 key 變化
    • 60秒內 ≥10000 key 變化
  • 優勢:單文件、備份易、災難恢復快、fork 子進程不阻塞主進程、大數據集啟動快。
  • 劣勢:定時快照間隔內數據可能丟失、fork 瞬間大內存佔用可能卡頓。

4.2 AOF(日志追加)

  • 記錄每條寫命令,重放重建數據。
  • 三種同步策略:
    • always:每寫入同步(最安全、最慢)。
    • everysec:每秒同步(默認、平衡)。
    • no:交給 OS,不保證(最快、可能丟數據)。
  • 優勢:數據安全性高、append-only 不易損壞、支持 rewrite 壓縮、日志可讀可人工修復。
  • 劣勢:文件體積大、恢復慢、everysec 下仍可能丟 1 秒數據。

4.3 混合持久化(Redis 4.0+)

  • aof-use-rdb-preamble yes:AOF 文件前綴 RDB 快照,後綴增量命令,兼顧啟動速度與數據安全。

4.4 手動觸發持久化 API

// 同步阻塞保存(慎用,阻塞主線程)
jedis.save();

// 異步非阻塞保存(推薦)
jedis.bgsave();

同步保存結果

五、綜合案例:汽車管理系統(序列化存儲)

5.1 實體類

@Data @AllArgsConstructor @NoArgsConstructor
public class Car implements Serializable {
    private static final long serialVersionUID = 1L;
    private int id;
    private String name;
    private double speed;
}

5.2 序列化工具類

public class SerializeUtil {
    public static byte[] serialize(Object obj) {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(baos)) {
            oos.writeObject(obj);
            return baos.toByteArray();
        } catch (IOException e) { throw new RuntimeException(e); }
    }

    @SuppressWarnings("unchecked")
    public static <T> T deserialize(byte[] bytes, Class<T> clazz) {
        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
             ObjectInputStream ois = new ObjectInputStream(bais)) {
            return (T) ois.readObject();
        } catch (IOException | ClassNotFoundException e) { throw new RuntimeException(e); }
    }
}

5.3 DAO 層封裝

public class CarDAO {
    private static final String KEY = "cars";
    private List<Car> cars = new ArrayList<>();

    public CarDAO() { load(); }

    public void save() {
        try (Jedis jedis = new Jedis("127.0.0.1", 6379)) {
            jedis.set(KEY.getBytes(), SerializeUtil.serialize(cars));
            jedis.bgsave();
        }
    }

    public void load() {
        try (Jedis jedis = new Jedis("127.0.0.1", 6379)) {
            byte[] data = jedis.get(KEY.getBytes());
            if (data != null && data.length > 0) {
                cars = SerializeUtil.deserialize(data, new TypeReference<List<Car>>() {});
            }
        }
    }

    // CRUD 方法均調用 save() 持久化
    public void add(Car car) { cars.add(car); save(); }
    public Car getById(int id) { return cars.stream().filter(c -> c.getId() == id).findFirst().orElse(null); }
    public void remove(int id) { cars.remove(getById(id)); save(); }
    public List<Car> getAll() { return cars; }
    public void setAll(List<Car> list) { this.cars = list; save(); }
}

5.4 JUnit 測試

public class CarTest {
    static CarDAO dao;

    @BeforeClass
    public static void init() { dao = new CarDAO(); }

    @Test public void testBatchAdd() {
        dao.setAll(Arrays.asList(
            new Car(1001, "Benz 600", 230),
            new Car(1002, "BMW X7+", 200),
            new Car(1003, "Audi A8", 180)
        ));
    }

    @Test public void testQueryAll() {
        dao.getAll().forEach(System.out::println);
    }

    @Test public void testAddOne() { dao.add(new Car(1004, "BYD F8", 150)); }
    @Test public void testGetById() { System.out.println(dao.getById(1001)); }
    @Test public void testRemove() { dao.remove(1004); }
}

測試結果

六、最佳實踐總結

場景建議
緩存純內存、無持久化、TTL 淘汰
會話存儲RDB 每分鐘快照 + AOF everysec
高併發計數器INCR 原子操作、無需持久化
分布式鎖SET NX EX + Lua 腳本釋放
生產部署Linux + Redis Cluster + Sentinel + AOF混合持久化

七、學習資源

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved