zoukankan      html  css  js  c++  java
  • redis开发小结

            随着缓存在web服务中用的越来越广泛,redis可以说成为了目前最流行的NoSQL数据库!redis与memcached最大的不同在于redis支持更多的数据类型,包括string、hash、list、set、sorted list等,所以redis的发展非常迅速,很多公司已将memcached替换为redis。我也做了一些redis的开发,现做一些小结。

    1. redis常用配置

         daemonize no     //Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程

         pidfile /var/run/redis.pid    //当Redis以守护进程方式运行时,可以通过pidfile指定pid写入的文件

         port 6379  //指定Redis监听端口,默认端口为6379

         bind 127.0.0.1  //只接受来至某IP的请求

         save <seconds> <changes>   //指定在多长时间内,有多少次更新操作

         rdbcompression yes  //指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大

         dbfilename dump.rdb   //指定本地数据库文件名,默认值为dump.rdb

         dir ./data    //指定本地数据库存放目录

         tcp-keepalive 60 //主动检测客户端链接是否正常,官方建议60s

         slaveof <masterip> <masterport>   // 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步

         appendonly no  //指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。

         appendfilename appendonly.aof  //指定更新日志文件名,默认为appendonly.aof

         vm-enabled no  //指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中

    2.  redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool  异常

         在开发中我遇到这个异常,翻来覆去看代码都没找到哪里写错了,最后无奈重启机器,把redis也重新启动,结果又不抛异常了!

         哦,我才发现原来我在redis的同一个数据库中即放了String字符串,又想放byte[]造成的,记住同一个数据库要放同一种数据结构!

    3.   Spring 与jedis整合

          Jedis 是 redis官方首选的 Java 客户端开发包。虽然spring-data-redis封装的更好,但本人还是喜欢直接使用jedis,这样灵活性更好。下面介绍spring与jedis配置:

    spring配置文件配置bean,主要是在spring容器中创建jedis需要的对象

        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> 
                <property name="maxTotal" value="50" />        
                <property name="testOnBorrow" value="true" />  
                <property name="maxIdle" value="10" />
                <property name="maxWaitMillis" value="1000" />
        </bean> 
        
        <bean  id="shardedJedisPool"  class="redis.clients.jedis.ShardedJedisPool">
             <constructor-arg  index="0"  ref="jedisPoolConfig" />  
             <constructor-arg index="1">  
                 <list>   
                      <bean class="redis.clients.jedis.JedisShardInfo">  
                           <constructor-arg  
                               index="0"  
                               value="127.0.0.1" />  
                           <constructor-arg  
                               index="1"  
                               value="6379"  
                               type="int" />  
                         </bean>  
                </list>  
            </constructor-arg> 
        </bean>

     接下来就可以在java持久层或服务层自动注入jedis对象:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Repository;
    
    import redis.clients.jedis.ShardedJedis;
    import redis.clients.jedis.ShardedJedisPool;
    
    @Repository
    public class RedisDao {
        @Autowired
        private ShardedJedisPool pool;
        
        public String getString(String key){
            ShardedJedis jedis = null;
            try {
                jedis = pool.getResource();
                return jedis.get(key);
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                pool.returnResourceObject(jedis);
            }
            return null;
        }
    
    }

    4.   redis监控

          查看redis内存使用情况:

             用redis-cli连接redis,用info memory查看内存占用情况

    $ ./src/redis-cli
    127.0.0.1:6379> info memory
    # Memory
    used_memory:37583536
    used_memory_human:35.84M
    used_memory_rss:40407040
    used_memory_peak:38312160
    used_memory_peak_human:36.54M
    used_memory_lua:35840
    mem_fragmentation_ratio:1.08
    mem_allocator:jemalloc-3.6.0
    used_memory:redis当前数据使用的内存,可能包括SWAP虚拟内存。
    used_memory_rss:redis当前占用的物理内存,与top命令查看的进程占用内存一致。
    mem_fragmentation_ratio:used_memory_rss/used_memory比值,这个值比较重要,当

    mem_fragmentation_ratio<1时,说明redis已经在使用SWAP,运行性能会受到很大影响。通常情况下该值比1大一如何避免mem_fragmentation_ratio<1?需要在redis.conf文件中正确配置三个参数:maxmemory、maxmemory-policy、maxmemory-samples。maxmemory:默认为0,在这种情况下,redis会尽可能使用物理内存,用完后尽可能使用虚拟内存。当使用SWAP时,性能会急剧下降,极限情况下redis可能会宕 这是运行环境中redis服务宕机的主要原因。因此在生产环境中一定要给该参数设置一个合理的值。当内存使用达到阀值时,redis会使用清除策略腾出内存。
    maxmemory-policy:定义清除策略。

    5. redis主从复制
    redis复制支持主从复制,一个主库可以挂多个从库,支持读写分离。同时从库可以再挂从库形成级联复制,可以用于解决大规模应用场景下服务的响应能力,而却由于存在多个数据源,数据丢失风险大为降低。

    6. redis持久化
    redis的持久化有RDB和AOF两种模式。两种模式可以单独存在也可以同时使用。RDB模式是在给定时间点将redis数据库快照保存为一个rdb文件。当redis重启时会根据这个快照文件重新加载数据。rdb模式可以在redis.conf文件中配置相关操作来触发:
    save 参数 , 设置定点保存快照数据规则,如:
    save 900 1 900秒后至少1个键值发生改变
    save 300 10 300秒后至少10个键值发生改变
    当最后有save ""语句时表示禁用rdb
    AOF模式是将没一写操作命令写入文件,在数据恢复时,AOF模式可以尽最大可能减少数据损失。因此,在两种模式都开启时,redis重启时会优先根据AOF文件进行数据恢复。

    7. redis sharding
    目前jedis已经支持sharding,她是采用consistent hashing,将key与节点name同时hash,用虚拟节点做映射匹配。另外还支持keyTagPattern模式,即抽取key的一部分keyTag做hashing,这样可以将一组相关联的key放入同一台redis节点上,避免跨节点访问相关数据。
    jedis sharding使用也很简单,只需要在选用合适的构造方法,填入合适的参数即可。
    如果在构造函数 public ShardedJedisPool(final GenericObjectPoolConfig poolConfig, List<JedisShardInfo> shards) 中shards传入多个redis节点即可支持分片。spring bean配置如下:
        <bean  id="shardedJedisPool"  class="redis.clients.jedis.ShardedJedisPool">
             <constructor-arg  index="0"  ref="jedisPoolConfig" />  
             <constructor-arg index="1">  
                 <list>   
                      <bean class="redis.clients.jedis.JedisShardInfo">  
                           <constructor-arg  index="0"  value="127.0.0.1" type="String"/>  
                           <constructor-arg  index="1"  value="node-1" type="String" /> 
                           <constructor-arg  index="2"  value="6379"  type="int" />  
                           <constructor-arg  index="3"  value="2000"  type="int" />  
                           <constructor-arg  index="4"  value="1"  type="int" />  
                         </bean>  
                         <bean class="redis.clients.jedis.JedisShardInfo">  
                           <constructor-arg  index="0"  value="127.0.0.1" type="String"/>  
                           <constructor-arg  index="1"  value="node-2" type="String" /> 
                           <constructor-arg  index="2"  value="6380"  type="int" />  
                           <constructor-arg  index="3"  value="2000"  type="int" />  
                           <constructor-arg  index="4"  value="3"  type="int" />  
                         </bean> 
                </list>  
            </constructor-arg> 
        </bean>

          这里采用的JedisShardInfo构造函数是:public JedisShardInfo(String host, String name, int port, int timeout, int weight),weight是分配key时该节点的权重,越大分配的key越多。

         

     
     
     
     

        

         

  • 相关阅读:
    ueditor1.4.3.all.js报错
    ueditor中FileUtils.getTempDirectory()找不到
    java后台验证码的生成
    applicationContext.xml重要配置
    Java代码实现文件上传(转载)
    jquery动态实现填充下拉框
    POI写入word docx 07 的两种方法
    POI读word docx 07 文件的两种方法
    POI转换word doc文件为(html,xml,txt)
    Linux中zip压缩和unzip解压缩命令详解
  • 原文地址:https://www.cnblogs.com/xingjunli/p/5034106.html
Copyright © 2011-2022 走看看