亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Redis優(yōu)惠券秒殺企業(yè)實(shí)戰(zhàn)

 更新時(shí)間:2022年07月26日 15:25:25   作者:Super_Leng  
本文主要介紹了Redis優(yōu)惠券秒殺企業(yè)實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、全局唯一ID

1. 全局ID生成器

每個(gè)店鋪都可以發(fā)布優(yōu)惠券:

當(dāng)用戶搶購時(shí),就會(huì)生成訂單并保存到tb_voucher_order這張表中,而訂單表如果使用數(shù)據(jù)庫自增ID就存在一些問題:

  • id的規(guī)律性太明顯
  • 受單表數(shù)據(jù)量的限制

所以tb_voucher_order表的主鍵不能用自增ID:

create table tb_voucher_order
(
    id          bigint                                        not null comment '主鍵'
        primary key,
    user_id     bigint unsigned                               not null comment '下單的用戶id',
    voucher_id  bigint unsigned                               not null comment '購買的代金券id',
    pay_type    tinyint(1) unsigned default 1                 not null comment '支付方式 1:余額支付;2:支付寶;3:微信',
    status      tinyint(1) unsigned default 1                 not null comment '訂單狀態(tài),1:未支付;2:已支付;3:已核銷;4:已取消;5:退款中;6:已退款',
    create_time timestamp           default CURRENT_TIMESTAMP not null comment '下單時(shí)間',
    pay_time    timestamp                                     null comment '支付時(shí)間',
    use_time    timestamp                                     null comment '核銷時(shí)間',
    refund_time timestamp                                     null comment '退款時(shí)間',
    update_time timestamp           default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新時(shí)間'
);

全局ID生成器,是一種在分布式系統(tǒng)下用來生成全局唯一ID的工具,一般要滿足下列特性:

為了增加ID的安全性,我們可以不直接使用Redis自增的數(shù)值,而是拼接一些其它信息:

D的組成部分:

  • 符號(hào)位:1bit,永遠(yuǎn)為0,表示正數(shù)
  • 時(shí)間戳:31bit,以秒為單位,可以使用69年
  • 序列號(hào):32bit,秒內(nèi)的計(jì)數(shù)器,支持每秒產(chǎn)生2^32個(gè)不同ID

編寫全局ID生成器代碼:

@Component
public class RedisIdWorker {
    /**
     * 開始時(shí)間戳,以2022.1.1為基準(zhǔn)計(jì)算時(shí)間差
     */
    private static final long BEGIN_TIMESTAMP = 1640995200L;
    /**
     * 序列號(hào)的位數(shù)
     */
    private static final int COUNT_BITS = 32;

    private StringRedisTemplate stringRedisTemplate;

    public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
     * 生成帶有業(yè)務(wù)前綴的redis自增id
     * @param keyPrefix
     * @return
     */
    public long nextId(String keyPrefix) {
        // 1.生成時(shí)間戳
        LocalDateTime now = LocalDateTime.now();
        long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
        long timestamp = nowSecond - BEGIN_TIMESTAMP;

        // 2.生成序列號(hào)
        // 2.1.獲取當(dāng)前日期,精確到天
        // 加上日期前綴,可以讓存更多同一業(yè)務(wù)類型的數(shù)據(jù),并且還能通過日期獲取當(dāng)天的業(yè)務(wù)數(shù)量,一舉兩得
        String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
        // 2.2.自增長
        long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);

        // 3.拼接并返回
        // 用于是數(shù)字類型的拼接,所以不能像拼接字符串那樣處理,而是通過位運(yùn)算將高32位存 符號(hào)位+時(shí)間戳,低32位存 序列號(hào)
        return timestamp << COUNT_BITS | count;
    }

    public static void main(String[] args) {
        LocalDateTime time = LocalDateTime.of(2022, 1, 1, 0, 0, 0);
        long second = time.toEpochSecond(ZoneOffset.UTC);
        System.out.println(second);// 1640995200
    }
}

測試全局ID生成器:

@SpringBootTest
class HmDianPingApplicationTests {
	@Resource
    private RedisIdWorker redisIdWorker;

    private ExecutorService executorService = Executors.newFixedThreadPool(500);

	@Test
    void testIdWorker() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(300);

        // 每個(gè)線程生成100個(gè)id
        Runnable task = () -> {
            for (int i = 0; i < 100; i++) {
                long id = redisIdWorker.nextId("order");
                System.out.println("id = " + id);
            }
            latch.countDown();
        };
        // 300個(gè)線程
        long begin = System.currentTimeMillis();
        for (int i = 0; i < 300; i++) {
            executorService.submit(task);
        }
        latch.await();
        long end = System.currentTimeMillis();
        System.out.println("time = " + (end - begin));
    }
}

測試結(jié)果:

2. 全局唯一ID生成策略

  • UUID(不是遞增的)
  • Redis自增
  • 雪花算法(snowflake)
  • 數(shù)據(jù)庫自增(單獨(dú)建一張表存自增id,分配到分庫分表后的表中)

3. Redis自增ID策略

  • 以日期作為前綴的key,方便統(tǒng)計(jì)訂單量
  • 自增ID的結(jié)構(gòu):時(shí)間戳 + 計(jì)數(shù)器

二、實(shí)現(xiàn)優(yōu)惠券秒殺下單

1. 添加優(yōu)惠券

每個(gè)店鋪都可以發(fā)布優(yōu)惠券,分為平價(jià)券和特價(jià)券。平價(jià)券可以任意購買,而特價(jià)券需要秒殺搶購:

優(yōu)惠券表信息:

  • tb_voucher:優(yōu)惠券的基本信息,優(yōu)惠金額、使用規(guī)則等(tb_voucher表的type字段區(qū)分是普通券還是秒殺券)
  • tb_seckill_voucher:優(yōu)惠券的庫存、開始搶購時(shí)間,結(jié)束搶購時(shí)間(秒殺券才需要填寫這些信息),同時(shí)秒殺券擁有普通券的基本信息(秒殺券表tb_seckill_voucher的主鍵id綁定的是普通券表tb_voucher的id)
create table tb_voucher
(
    id           bigint unsigned auto_increment comment '主鍵'
        primary key,
    shop_id      bigint unsigned                               null comment '商鋪id',
    title        varchar(255)                                  not null comment '代金券標(biāo)題',
    sub_title    varchar(255)                                  null comment '副標(biāo)題',
    rules        varchar(1024)                                 null comment '使用規(guī)則',
    pay_value    bigint(10) unsigned                           not null comment '支付金額,單位是分。例如200代表2元',
    actual_value bigint(10)                                    not null comment '抵扣金額,單位是分。例如200代表2元',
    type         tinyint(1) unsigned default 0                 not null comment '0,普通券;1,秒殺券',
    status       tinyint(1) unsigned default 1                 not null comment '1,上架; 2,下架; 3,過期',
    create_time  timestamp           default CURRENT_TIMESTAMP not null comment '創(chuàng)建時(shí)間',
    update_time  timestamp           default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新時(shí)間'
);
create table tb_seckill_voucher
(
    voucher_id  bigint unsigned                     not null comment '關(guān)聯(lián)的優(yōu)惠券的id'
        primary key,
    stock       int(8)                              not null comment '庫存',
    create_time timestamp default CURRENT_TIMESTAMP not null comment '創(chuàng)建時(shí)間',
    begin_time  timestamp default CURRENT_TIMESTAMP not null comment '生效時(shí)間',
    end_time    timestamp default CURRENT_TIMESTAMP not null comment '失效時(shí)間',
    update_time timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新時(shí)間'
)
    comment '秒殺優(yōu)惠券表,與優(yōu)惠券是一對一關(guān)系';

2. 編寫添加秒殺券的接口

主要代碼:

@RestController
@RequestMapping("/voucher")
public class VoucherController {

    @Resource
    private IVoucherService voucherService;

    /**
     * 新增秒殺券
     * @param voucher 優(yōu)惠券信息,包含秒殺信息
     * @return 優(yōu)惠券id
     */
    @PostMapping("seckill")
    public Result addSeckillVoucher(@RequestBody Voucher voucher) {
        voucherService.addSeckillVoucher(voucher);
        return Result.ok(voucher.getId());
    }
}
@Service
public class VoucherServiceImpl extends ServiceImpl<VoucherMapper, Voucher> implements IVoucherService {

    @Resource
    private ISeckillVoucherService seckillVoucherService;

    @Override
    @Transactional
    public void addSeckillVoucher(Voucher voucher) {
        // 保存優(yōu)惠券
        save(voucher);
        // 保存秒殺信息
        SeckillVoucher seckillVoucher = new SeckillVoucher();
        seckillVoucher.setVoucherId(voucher.getId());
        seckillVoucher.setStock(voucher.getStock());
        seckillVoucher.setBeginTime(voucher.getBeginTime());
        seckillVoucher.setEndTime(voucher.getEndTime());
        seckillVoucherService.save(seckillVoucher);
    }
}

測試添加:

測試結(jié)果:

三、實(shí)現(xiàn)秒殺下單

下單時(shí)需要判斷兩點(diǎn):

  • 秒殺是否開始或結(jié)束,如果尚未開始或已經(jīng)結(jié)束則無法下單
  • 庫存是否充足,不足則無法下單

主要代碼:

@RestController
@RequestMapping("/voucher-order")
public class VoucherOrderController {
    @Resource
    private IVoucherOrderService voucherOrderService;

    @PostMapping("seckill/{id}")
    public Result seckillVoucher(@PathVariable("id") Long voucherId) {
        return voucherOrderService.seckillVoucher(voucherId);
    }
}
@Service
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {

    @Resource
    private ISeckillVoucherService seckillVoucherService;

    @Resource
    private RedisIdWorker redisIdWorker;

    @Override
    public Result seckillVoucher(Long voucherId) {
        // 1.查詢優(yōu)惠券
        SeckillVoucher voucher = seckillVoucherService.getById(voucherId);
        // 2.判斷秒殺是否開始
        if (voucher.getBeginTime().isAfter(LocalDateTime.now())) {
            // 尚未開始
            return Result.fail("秒殺尚未開始!");
        }
        // 3.判斷秒殺是否已經(jīng)結(jié)束
        if (voucher.getEndTime().isBefore(LocalDateTime.now())) {
            // 尚未開始
            return Result.fail("秒殺已經(jīng)結(jié)束!");
        }
        // 4.判斷庫存是否充足
        if (voucher.getStock() < 1) {
            // 庫存不足
            return Result.fail("庫存不足!");
        }
        //5,扣減庫存
        boolean success = seckillVoucherService.update()
                .setSql("stock= stock -1")
                .eq("voucher_id", voucherId).update();
        if (!success) {
            // 扣減庫存失敗
            return Result.fail("庫存不足!");
        }
        // 6.創(chuàng)建訂單
        VoucherOrder voucherOrder = new VoucherOrder();
        // 6.1.訂單id
        long orderId = redisIdWorker.nextId("order");
        voucherOrder.setId(orderId);
        // 6.2.用戶id
        Long userId = UserHolder.getUser().getId();
        voucherOrder.setUserId(userId);
        // 6.3.代金券id
        voucherOrder.setVoucherId(voucherId);
        save(voucherOrder);

        return Result.ok(orderId);

    }
}

簡單測試秒殺成功:

扣減庫存成功:

四、超賣問題

當(dāng)有大量請求同時(shí)訪問時(shí),就會(huì)出現(xiàn)超賣問題

超賣問題是典型的多線程安全問題,針對這一問題的常見解決方案就是加鎖:

1. 加鎖方式 - 樂觀鎖

樂觀鎖的關(guān)鍵是判斷之前查詢得到的數(shù)據(jù)是否有被修改過,常見的方式有兩種:

(1)版本號(hào)法

(2)CAS法

  • 用庫存代替了版本號(hào),可以少加一個(gè)字段
  • 扣庫存時(shí),與查詢時(shí)的庫存比較,沒被修改則可以扣減庫存

2. 樂觀鎖解決超賣問題

樂觀鎖方式,通過CAS判斷前后庫存是否一致,解決超賣問題:

// 之前的代碼
boolean success = seckillVoucherService.update()
                .setSql("stock= stock -1")
                .eq("voucher_id", voucherId).update();
                
// 樂觀鎖方式,通過CAS判斷前后庫存是否一致,解決超賣問題                
boolean success = seckillVoucherService.update()
            .setSql("stock= stock -1") // set stock = stock -1
            .eq("voucher_id", voucherId).eq("stock",voucher.getStock()).update(); // where id = ? and stock = ?

又出現(xiàn)新的問題:

  • 假設(shè)100個(gè)線程同時(shí)請求,但通過CAS判斷后,只有一個(gè)線程能扣減庫存成功,其余99個(gè)線程全部失敗
  • 此時(shí),庫存剩余99,但是實(shí)際業(yè)務(wù)可以滿足其余99個(gè)線程扣減庫存
  • 雖然能解決超賣問題,但是設(shè)計(jì)不合理

所以為了解決失敗率高的問題,需要進(jìn)一步改進(jìn):

通過CAS 不再 判斷前后庫存是否一致,而是判斷庫存是否大于0

boolean success = seckillVoucherService.update()
                .setSql("stock= stock -1")
                .eq("voucher_id", voucherId).gt("stock",0).update(); // where id = ? and stock > 0

3. 小結(jié)

超賣這樣的線程安全問題,解決方案有哪些?
(1)悲觀鎖:添加同步鎖,讓線程串行執(zhí)行

  • 優(yōu)點(diǎn):簡單粗暴
  • 缺點(diǎn):性能一般

(2)樂觀鎖:不加鎖,在更新時(shí)判斷是否有其它線程在修改

  • 優(yōu)點(diǎn):性能相對悲觀鎖好(但是仍然需要同時(shí)查數(shù)據(jù)庫,影響性能)
  • 缺點(diǎn):存在成功率低的問題(可以采用分段鎖方式提高成功率)

五、一人一單問題

需求:修改秒殺業(yè)務(wù),要求同一個(gè)優(yōu)惠券,一個(gè)用戶只能下一單

在扣減庫存之前,加上一人一單的邏輯:

// 5.一人一單邏輯
Long userId = UserHolder.getUser().getId();
  // 5.1.查詢訂單數(shù)量
  int count = query().eq("user_id", userId).eq("voucher_id", voucherId).count();
  // 5.2.判斷是否下過單
  if (count > 0) {
      // 用戶已經(jīng)購買過了
      return Result.fail("用戶已經(jīng)購買過一次!");
  }

此處仍會(huì)出現(xiàn)并發(fā)問題,當(dāng)同一用戶模擬大量請求同時(shí)查詢是否下過單時(shí),如果正好都查詢出count為0,就會(huì)跳過判斷繼續(xù)執(zhí)行扣減庫存的邏輯,此時(shí)就會(huì)出現(xiàn)一人下多單的問題

解決方法:

  • 由于是判斷查詢的數(shù)據(jù)是否存在,而不是像之前判斷查詢的數(shù)據(jù)是否修改過
  • 所以這里只能加悲觀鎖

1. 加鎖分析

  • 首先將一人一單之后的邏輯全部加鎖,所以將一人一單之后的邏輯抽取出一個(gè)方法進(jìn)行加鎖,public Result createVoucherOrder(Long voucherId)
  • 如果直接在方法上加鎖,則鎖的是this對象,鎖的對象粒度過大,就算是不同的人執(zhí)行都會(huì)阻塞住,影響性能,public synchronized Result createVoucherOrder(Long voucherId)
  • 所以將鎖的對象改為userId,但是不能直接使用synchronized (userId),因?yàn)槊看螆?zhí)行Long userId = UserHolder.getUser().getId();雖然值一樣,但是對象不同,因此需要這樣加鎖 synchronized (userId.toString().intern()),intern()表示每次從字符串常量池中獲取,這樣值相同時(shí),對象也相同
  • 為了防止事務(wù)還沒提交就釋放鎖的問題,則不能將鎖加在createVoucherOrder方法內(nèi)部,例如:
@Transactional
public Result createVoucherOrder(Long voucherId) {
	synchronized (userId.toString().intern()) {
		。。。
	}
}

而是需要等事務(wù)提交完再釋放鎖,例如:

synchronized (userId.toString().intern()) {
 	// 獲取代理對象(事務(wù))
    IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
    return proxy.createVoucherOrder(voucherId);
}

2. 事務(wù)分析

由于只有一人一單之后的邏輯涉及到修改數(shù)據(jù)庫,所以只需對該方法加事務(wù)
@Transactional
public Result createVoucherOrder(Long voucherId)

由于只對createVoucherOrder方法加了事務(wù),而該方法是在seckillVoucher方法中被調(diào)用,seckillVoucher方法又沒有加事務(wù),為了防止事務(wù)失效,則不能直接在seckillVoucher方法調(diào)用createVoucherOrder方法,例如:

@Override
public Result seckillVoucher(Long voucherId) {
	。。。。
	synchronized (userId.toString().intern()) {
        return this.createVoucherOrder(voucherId);
    }
}

而是需要通過代理對象調(diào)用createVoucherOrder方法,因?yàn)锧Transactional事務(wù)注解的原理是通過獲取代理對象執(zhí)行目標(biāo)對象的方法,進(jìn)行AOP操作,所以需要這樣:

@Override
public Result seckillVoucher(Long voucherId) {
	。。。。
	// 獲取代理對象(事務(wù))
    IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
    return proxy.createVoucherOrder(voucherId);
}

并且還要引入依賴:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>

還要開啟注解暴露出代理對象:

@EnableAspectJAutoProxy(exposeProxy = true)
@MapperScan("com.hmdp.mapper")
@SpringBootApplication
public class HmDianPingApplication {
    public static void main(String[] args) {
        SpringApplication.run(HmDianPingApplication.class, args);
    }
}

完整VoucherOrderServiceImpl代碼:

@Service
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {

    @Resource
    private ISeckillVoucherService seckillVoucherService;

    @Resource
    private RedisIdWorker redisIdWorker;

    @Override
    public Result seckillVoucher(Long voucherId) {
        // 1.查詢優(yōu)惠券
        SeckillVoucher voucher = seckillVoucherService.getById(voucherId);
        // 2.判斷秒殺是否開始
        if (voucher.getBeginTime().isAfter(LocalDateTime.now())) {
            // 尚未開始
            return Result.fail("秒殺尚未開始!");
        }
        // 3.判斷秒殺是否已經(jīng)結(jié)束
        if (voucher.getEndTime().isBefore(LocalDateTime.now())) {
            // 尚未開始
            return Result.fail("秒殺已經(jīng)結(jié)束!");
        }
        // 4.判斷庫存是否充足
        if (voucher.getStock() < 1) {
            // 庫存不足
            return Result.fail("庫存不足!");
        }

        Long userId = UserHolder.getUser().getId();
        synchronized (userId.toString().intern()) {
            // 獲取代理對象(事務(wù))
            IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
            return proxy.createVoucherOrder(voucherId);
        }
        
    }

    @Transactional
    public Result createVoucherOrder(Long voucherId) {

        // 5.一人一單邏輯
        Long userId = UserHolder.getUser().getId();
        // 5.1.查詢訂單數(shù)量
        int count = query().eq("user_id", userId).eq("voucher_id", voucherId).count();
        // 5.2.判斷是否下過單
        if (count > 0) {
            // 用戶已經(jīng)購買過了
            return Result.fail("用戶已經(jīng)購買過一次!");
        }

        // 6,扣減庫存
        // 樂觀鎖方式,通過CAS判斷庫存是否大于0,解決超賣問題:
        boolean success = seckillVoucherService.update()
                .setSql("stock= stock -1")
                .eq("voucher_id", voucherId).gt("stock",0).update(); // where id = ? and stock > 0

        if (!success) {
            // 扣減庫存失敗
            return Result.fail("庫存不足!");
        }

        // 7.創(chuàng)建訂單
        VoucherOrder voucherOrder = new VoucherOrder();
        // 7.1.訂單id
        long orderId = redisIdWorker.nextId("order");
        voucherOrder.setId(orderId);
        // 7.2.用戶id
        voucherOrder.setUserId(userId);
        // 7.3.代金券id
        voucherOrder.setVoucherId(voucherId);
        save(voucherOrder);

        // 8.返回訂單id
        return Result.ok(orderId);
    }
    
}

六、集群模式下并發(fā)安全問題

通過加鎖可以解決在單機(jī)情況下的一人一單安全問題,但是在集群模式下就不行了。

我們將服務(wù)啟動(dòng)兩份,端口分別為8081和8082:

然后修改nginx的conf目錄下的nginx.conf文件,配置反向代理和負(fù)載均衡:

修改完后,重新加載nginx配置文件:

現(xiàn)在,用戶請求會(huì)在這兩個(gè)節(jié)點(diǎn)上負(fù)載均衡,再次測試下是否存在線程安全問題:

訪問8081端口的線程進(jìn)入了synchronized中

訪問8082端口的線程也進(jìn)入了synchronized中

最終同一個(gè)用戶下了2單扣了2個(gè)庫存,所以在集群模式下,出現(xiàn)了一人多單的問題:

分析:

  • 鎖的原理是每個(gè)JVM中都有一個(gè)Monitor作為鎖對象,所以當(dāng)對象相同時(shí),獲取的就是同一把鎖
  • 但是不同的JVM中的Monitor不同,所以獲取的不是同一把鎖
  • 因此集群模式下,加synchronized鎖也會(huì)出現(xiàn)并發(fā)安全問題,需要加分布式鎖

 到此這篇關(guān)于Redis優(yōu)惠券秒殺企業(yè)實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)Redis 優(yōu)惠券秒殺 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis中的數(shù)據(jù)過期策略詳解

    Redis中的數(shù)據(jù)過期策略詳解

    這篇文章主要介紹了Redis中的數(shù)據(jù)過期策略,文中通過示例代碼介紹的很詳細(xì),相信對大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,有需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-01-01
  • redis中跳表zset的具體使用

    redis中跳表zset的具體使用

    Redis跳表zset是一種結(jié)合了跳表和有序集合的高效數(shù)據(jù)結(jié)構(gòu),適用于實(shí)現(xiàn)排序和大規(guī)模數(shù)據(jù)的快速查詢,本文主要介紹了redis中跳表zset的具體使用,感興趣的可以了解一下
    2024-01-01
  • redis實(shí)現(xiàn)共同好友的思路詳解

    redis實(shí)現(xiàn)共同好友的思路詳解

    微信朋友圈大家都玩過吧,那么朋友圈的點(diǎn)贊、評論只能看到自己好友的信息是怎么操作的呢?下面通過本文給大家分享下此功能的實(shí)現(xiàn)流程,對redis實(shí)現(xiàn)共同好友的方法感興趣的朋友一起看看吧
    2021-05-05
  • redis 過期策略及內(nèi)存回收機(jī)制解析

    redis 過期策略及內(nèi)存回收機(jī)制解析

    這篇文章主要介紹了redis 過期策略及內(nèi)存回收機(jī)制,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Redis BloomFilter實(shí)例講解

    Redis BloomFilter實(shí)例講解

    這篇文章主要介紹了Redis BloomFilter實(shí)例。BloomFilter不需要存儲(chǔ)key,節(jié)省空間,在某些對保密要求非常嚴(yán)格的場合有優(yōu)勢。想要進(jìn)一步了解BloomFilter運(yùn)用實(shí)例的小伙伴可以了解一下這篇文章
    2021-09-09
  • redis中RDB(Redis Data Base)的機(jī)制

    redis中RDB(Redis Data Base)的機(jī)制

    本文主要介紹了redis中RDB(Redis Data Base)的機(jī)制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Linux服務(wù)器快速安裝Redis6.0步驟示例詳解

    Linux服務(wù)器快速安裝Redis6.0步驟示例詳解

    這篇文章主要為大家介紹了Linux服務(wù)器快速安裝Redis6.0步驟示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • RediSearch加RedisJSON大于Elasticsearch的搜索存儲(chǔ)引擎

    RediSearch加RedisJSON大于Elasticsearch的搜索存儲(chǔ)引擎

    這篇文章主要為大家介紹了RediSearch加RedisJSON大于Elasticsearch的王炸使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Redis 的各項(xiàng)功能主要解決了什么問題

    Redis 的各項(xiàng)功能主要解決了什么問題

    Redis是一個(gè)基于BSD開源的項(xiàng)目,是一個(gè)把結(jié)構(gòu)化的數(shù)據(jù)放在內(nèi)存中的一個(gè)存儲(chǔ)系統(tǒng),你可以把它作為數(shù)據(jù)庫,緩存和消息中間件來使用。這篇文章主要介紹了Redis 的各項(xiàng)功能主要解決了什么問題,需要的朋友可以參考下
    2018-10-10
  • 詳解Redis中key的命名規(guī)范和值的命名規(guī)范

    詳解Redis中key的命名規(guī)范和值的命名規(guī)范

    這篇文章主要介紹了詳解Redis中key的命名規(guī)范和值的命名規(guī)范,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12

最新評論