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越多。

         

     
     
     
     

        

         

  • 相关阅读:
    eclipse中的Invalid text string (xxx).
    在jsp文件中出现Unknown tag (c:out)
    eclipse 界面复原
    ecilpse 纠错插件
    Multiple annotations found at this line:- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    Port 8080 required by Tomcat v9.0 Server at localhost is already in use. The server may already be running in another process, or a system process may be using the port.
    调用第三方https接口
    调用第三方http接口
    创建带值枚举
    spring整合redis之Redis配置文件
  • 原文地址:https://www.cnblogs.com/xingjunli/p/5034106.html
Copyright © 2011-2022 走看看