redis string

string 的2种数据结构,3种编码方式

string结构图

2种数据结构

int:value值是一个整数类型,

SDS:value是字符串类型

3种编码方式

1.int

如果一个字符串对象保存的是一个整数值,那么此字符串的编码是int

结构:

2.embstr

如果字符串的长度在小于44个字节(总字节数小于64个字节)使用的编码方式是embstr方式。由内存分配器一次分配RedisObject和sdshdr

结构:

3.raw

如果字符串的长度大于44个字节(总字节数大于64个字节),此时redis认为这是一个大字符串,使用的编码方式是raw方式。由内存分配器俩次分配RedisObject和sdshdr

结构:

embstr和raw的区别 

1.embstr使用一次内存分配,raw使用俩次没存分配。在数据量小的情况下使用embstr方式可以减少寻址时间

2.内存回收次数也不一样,embstr只需要一次。raw需要俩次

扩容方式

字符串长度在小于1M的情况下,每次追加如果能容纳下新增加的字符串长度,那么不做任何操作,反之扩容为原来的一倍。如果字符串长度大于1M。之后的扩容只会扩1M的冗余空间,防止浪费.

string常用功能

1.做缓存。value可以是一个普通字符串,也可以是json对象

2.计数器。int类型可以通过incr每次加一 或者incrby 加指定数

3.分布式锁

public class RedisLock {
  private static final String LOCK_SUCCESS = "OK";
  private static final Long RELEASE_SUCCESS = 1L;
  // 锁的默认超时时间
  private int expireTime = 10 * 1000;
  // 锁默认等待时间
  private int waitTime = 5 * 1000;

  private Jedis jedis;
  private String key;
  /**
   * 分布式环境下应该使用分布式id
   */
  private String value = null;

  public RedisLock(Jedis jedis, String key) {
    this.jedis = jedis;
    this.key = key;
  }

  public RedisLock(Jedis jedis, String key, int expireTime, int waitTime) {
    this.jedis = jedis;
    this.key = key;
    this.expireTime = expireTime;
    this.waitTime = waitTime;
  }

  /***
   * 加锁
   * @param value   分布式id
   * @return
   */
  public synchronized boolean lock(String value) {
    if (value == null) {
      throw new RuntimeException("value is null");
    }
    try {
      // 超过等待时间,加锁失败
      long waitEnd = System.currentTimeMillis() + waitTime + 1;
      SetParams setParams = new SetParams();
      setParams.nx();
      setParams.px(expireTime);
      while (System.currentTimeMillis() < waitEnd) {
        String result = jedis.set(key, value, setParams);
        if (LOCK_SUCCESS.equals(result)) {
          this.value = value;
          return true;
        }
        try {
          Thread.sleep(10);
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
        }
      }
    } catch (Exception ex) {
    }
    return false;
  }

  /***
   * 释放锁
   * @return
   */
  public synchronized boolean unLock() {
    if (value == null) {
      return false;
    }
    //判断key和删除key必须是一个原子操作
    String lua = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    try {
      Object result = jedis.eval(lua, Collections.singletonList(key), Collections.singletonList(value));
      if (RELEASE_SUCCESS.equals(result)) {
        return true;
      }
    } catch (Exception e) {
    }
    return false;
  }
}
public class JedisLock {
  private final Jedis client;
  private final String lockKey;
  private final int expireTime;
  private final int waitTime;
  private boolean locked = false;

  public JedisLock(Jedis client, String lockKey, int expireTime, int waitTime) {
    this.client = client;
    this.lockKey = lockKey;
    this.expireTime = expireTime;
    this.waitTime = waitTime;
  }

  public synchronized boolean lock() throws InterruptedException {
    int timeout = this.waitTime;

    while(timeout >= 0) {
      long expires = System.currentTimeMillis() + (long)this.expireTime + 1L;
      String expiresStr = String.valueOf(expires);
      if (this.client.setNx(this.lockKey, expiresStr)) {
        this.locked = true;
        return true;
      }

      String currentValueStr = this.client.get(this.lockKey);
      if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
        String oldValueStr = this.client.getSet(this.lockKey, expiresStr);
        if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
          this.locked = true;
          return true;
        }
      }

      timeout -= 50;
      this.wait(50L);
    }

    return false;
  }

  public synchronized void unlock() {
    if (this.locked) {
      this.client.delKey(this.lockKey);
      this.locked = false;
    }

  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值