Redis安装及Jedis使用笔记

一、部署 

单机模式(standalone)部署
1. Linux下安装gcc,(用于编译c文件),root用户执行
  $ yum install gcc
2. 在/opt下安装redis
  $ cd /opt
  $ wget http://download.redis.io/releases/redis-5.0.5.tar.gz
  $ tar xzf redis-5.0.5.tar.gz
  $ cd redis-5.0.5
  $ make 或者 make MALLOC=libc
3. 启动reids
  $ src/redis-server (redis-server在编译成功后才生成)

出现的错误,将"$ make"命令改成"$ make MALLOC=libc" 即可

reids启动后界面,不能退出,否则就关闭了:(如下,可以以守护进程方式启动)

4. 配置redis以守护进程方式启动
  $ vi /opt/redis-5.0.5/redis.conf
  按键"shift :",进入底线命令行模式,查找"daemonize"单词,如下
  :/daemonize (回车)
  找到后,按键"i",进入编辑模式,修改 daemonize yes,保存退出
  
5. 以配置文件启动reids,这是就能以守护进程方式启动了
  $ cd /opt/redis-5.0.5
  $ src/redis-server redis.conf
  查看是否启动
  $ ps aux | grep reids-server

6. 使用客户端交互
  $ /opt/redis-5.0.5/src/redis-cli
  注:(默认无密码登陆)如果登陆设置了密码,需要输入密码,否则无权访问
    127.0.0.1:6379> auth 123456
    OK
  新增
    127.0.0.1:6379> set foo bar
    OK
  获取
    127.0.0.1:6379> get foo
    "bar"
  删除
    127.0.0.1:6379> del foo
    (integer) 1
    127.0.0.1:6379> get foo
    (nil)
  关闭redis服务(通过客户端关闭)
    127.0.0.1:6379> shutdown
  退出客户端
    127.0.0.1:6379> exit (连接时退出客户端)
    not connected> exit (未连接时退出客户端)
** 配置文件redis.conf
配置1:
  bind 127.0.0.1 (默认配置)
  意为:禁止外网访问,只允许本地访问
  bind 127.0.0.1 192.168.190.200
  意为:允许多个IP访问(用空格分隔)
  bind 0.0.0.0
  意为:允许任意IP访问

配置2:
  requirepass foobared (默认注释掉,无密码登陆)
  意为:授权登陆密码,需要设置复杂强度高的密码,否则由于其高性能并发性,容易被碰撞破解
  本地测试用,可以设为:
  requirepass 123456

配置3:
  daemonize yes
  意为:以守护进程方式后台启动运行

 

二、Redis客户端 Jedis使用(Scala实现)

package sparkstreaming_action.userbehavior.dao

import redis.clients.jedis.Jedis
import redis.clients.jedis.exceptions.JedisConnectionException
import scala.collection.mutable.ArrayBuffer
import org.apache.log4j.LogManager

import sparkstreaming_action.userbehavior.util.Conf

/**
 *  *Redis 客户端编程 主页:https://redis.io/clients
 *  以下是相关推荐:
 *  (推荐)jedis 源码及教程:https://github.com/xetorthio/jedis/wiki
 *          oschina jedis 2.1.0 API 使用手册:http://tool.oschina.net/uploads/apidocs/redis/clients/jedis/Jedis.html
 *  (推荐)scala-redis 源码:https://github.com/debasishg/scala-redis
 *  spark-redis 源码:https://github.com/RedisLabs/spark-redis/blob/master/doc/getting-started.md
 *  sedis 源码:https://github.com/pk11/sedis
 */

/** 
 *  Redis util
 */
object RedisUtil {
  
  @transient lazy val log = LogManager.getLogger(this.getClass)
  
  /**
   *  Redis 读写分离
   */
  // Redis 客户端 读连接
  var readJedis: Jedis = _
  // Redis 客户端 写连接
  var writeJedis: Jedis = _
  
  /** 验证 Redis 连接是否可用,不可用时重连
   *  @return Unit
   */
  def checkAlive: Unit = {
    // 读连接验证
    if (!isConnected(readJedis)) {
      readJedis = reConnect(readJedis)
    }
    // 写连接验证
    if (!isConnected(writeJedis)) {
      writeJedis = reConnect(writeJedis)
    }
  }
  
  /**
   *  获取 Redis 客户端连接
   *  @param ip Redis server host
   *  @param port Redis server port
   *  @param passwd Redis授权连接密码
   *  @return Jedis 返回Redis客户端访问对象
   */
  def getConn(ip: String, port: Int, passwd: String): Jedis = {
    // 创建 Jedis连接,连接超时时间:5000ms
    val jedis = new Jedis(ip, port, 5000)
    jedis.connect
    // 设置登陆密码
    if (passwd != null && passwd.length() > 0) {
      /** 连接 Redis 密码,需要设置高强度一点、长一点
       *    由于Redis的高性能特性,很有可能利用并发在短时间内尝试很多密码,造成密码破译
       */
      jedis.auth(passwd)
    }
    jedis
  }
  
  /** 判断 Redis 客户端是否连接
   *  @param jedis Redis 客户端
   *  @return Boolean true|false
   */
  def isConnected(jedis: Jedis): Boolean = jedis != null && jedis.isConnected()
  
  /** 重连 Redis 客户端
   *  @param jedis 原 Redis 客户端
   *  @return jedis 重连后的 Redis 客户端
   */
  def reConnect(jedis: Jedis): Jedis = {
    println("reconnecting ...")
    disConnect(jedis)
    getConn(Conf.redisIp, Conf.redisPort, Conf.passwd)
  }
  
  /** 释放 Redis 客户端连接
   *  @param jedis Redis 客户端
   *  @return Unit
   */
  def disConnect(jedis: Jedis): Unit = {
    if (jedis != null && jedis.isConnected()) {
      jedis.close()
    }
  }
  
  /** 键值对 批量 写入 Redis 存储
   *  @param kvs 键值对二元组列表(键值对需转成字节数组存储)
   *  @return Unit
   */
  def batchSet(kvs: Seq[(Array[Byte], Array[Byte])]): Unit = {
    try {
      // 检查连接
      checkAlive
      // 遍历键值对列表
      var i = 0
      while (i < kvs.length) {
        /**
         *  每 batchSize 条插入命令,作为一个批次执行
         *  每一批次执行,通过获取一个管道实现
         */
        // 获取管道,便于一次执行大量命令
        val pipeline = writeJedis.pipelined()
        // 每批发送指定数量(batchSize)命令
        val target = i + Conf.batchSize
        println(s"set ${new String(kvs(i)._1)} to ${new String(kvs(i)._2)}")
        while (i < target && i < kvs.length) {
          // 插入键值对命令
          pipeline.set(kvs(i)._1, kvs(i)._2)
          // 设置键超时命令(意味着此键是不稳定的,到期后键会被 Redis server 删除)
          pipeline.expire(kvs(i)._1, Conf.EXPIRE_DURATION)
          i += 1
        }
        // 读取所有指令响应同步到管道,并关闭此管道
        pipeline.sync()
      }
    } catch {
      case connEx: JedisConnectionException => 
        log.error("[batchSet_connError]", connEx)
        // 连接异常时,重连
        writeJedis = reConnect(writeJedis)
      case ex: Exception => 
        log.error("[batchSet_Error]", ex)
    }
    
  }
  
  /** 按键 批量 读出 Redis 存储值
   *  @param keys 键列表
   *  @return 批量返回键对应的值列表(字节数组列表)
   */
  def batchGet(keys: Seq[String]): ArrayBuffer[Array[Byte]] = {
    // 定义返回的值列表
    val res = ArrayBuffer[Array[Byte]]()
    try {
      // 检查连接
      checkAlive
      // 遍历键列表
      var i = 0
      while (i < keys.length) {
        // 获取键的值
        val resp = readJedis.get(keys(i).getBytes)
        res += resp
        i += 1
      }
    } catch {
      case connEx: JedisConnectionException => 
        log.error("[batchGet_connError]", connEx)
        // 连接异常时,重连
        readJedis = reConnect(readJedis)
      case ex: Exception => 
        log.error("[batchGet_Error]", ex)
    }
    res
  }
  
}

参考文章:

1. linus 下redis守护进程启动

2. Redis安装与调试

3. redis安装zmalloc.h:50:31: 致命错误:jemalloc/jemalloc.h:没有那个文件或目录

4. https://redis.io/download

5. (拓展参考):Redis分布式集群搭建

6. Redis中文网(含教程)

7. Redis 客户端 工具(含Jedis)

8. Jedis 2.1.0 API 手册

9. Jedis 源码分析

10. Redis未授权访问详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值