精华内容
下载资源
问答
  • rides教学视频

    2018-03-11 10:35:59
    ArrayList: 分配的内存单元是连续的 查询快, 单向链表:分配的空间不是连续的.查询慢, 增删快 双向链表:分配的空间不是连续的.查询慢, 增删快
  • Bike-rides-源码

    2021-03-11 10:29:06
    骑自行车
  • linux安装rides.doc

    2019-07-12 10:42:05
    linux安装rides.doc
  • c#的Rides演示demo

    2019-01-29 14:30:21
    c#的Rides演示demo 不会改资源积分 默认就是5分 我也没办法 我想2分就行了 但是没有办法改
  • RIDES

    千次阅读 2018-05-04 16:01:36
    github下载地址:https://github.com/MSOpenTech/redis/tags启动命令redis-server redis.windows.conf启动失败:连接失败:1.redis-cli.exe2.shutdown3.exit4.redis-server redis.windows.conf设置服务命令redis-...

    github下载地址:https://github.com/MSOpenTech/redis/tags

    启动命令

    redis-server redis.windows.conf

    启动失败:连接失败:

    1.redis-cli.exe

    2.shutdown

    3.exit

    4.redis-server redis.windows.conf

    设置服务命令

    redis-server --service-install redis.windows-service.conf --loglevel verbose

    常用的redis服务命令。

    卸载服务:redis-server --service-uninstall

    开启服务:redis-server --service-start

    停止服务:redis-server --service-stop


    展开全文
  • 这个可让您将Uber Rides API集成到您的iOS应用中。 要求 iOS 8.0以上 Xcode 10.0以上 迅捷4.2+ 安装Uber Rides SDK 要安装Uber Rides SDK,您可以使用 , 或将其手动添加到您的项目中 pod 'UberRides' , '~> 0.13'...
  • java项目中rides的使用

    万次阅读 2019-03-22 19:43:29
    项目开发中一些特定的数据我们不一定要关系型数据库来存储,使用非关系型数据库反而更方便读取数据,效率高,这里介绍一下在java中rides的使用 1. 导入rides所需要的相关依赖jar包(在pom文件中): <!-- jedis...

    项目开发中一些特定的数据我们不一定要关系型数据库来存储,使用非关系型数据库反而更方便读取数据,效率高,这里介绍一下在java中rides的使用

    1. 导入rides所需要的相关依赖jar包(在pom文件中):

    		<!-- jedis工具包 -->
    		<dependency>
    			<groupId>redis.clients</groupId>
    			<artifactId>jedis</artifactId>
    			<version>2.4.2</version>
    		</dependency>
    		<!-- gson依赖,用于把对象存在redis中转换格式-->
    		<dependency>
    			<groupId>com.google.code.gson</groupId>
    			<artifactId>gson</artifactId>
    			<version>2.8.5</version>
    		</dependency>
    

    2. 在applicationContext.xml配置文件中创建rides连接池,以及properties文件的配置:

    	<!-- 读取properties配置文件的标签,因为多个文件使用的是一个IOC容器,所以只要在一个文件中读取就可以 -->
        <context:property-placeholder location="classpath:properties/*.properties"/>
    	<!-- 配置redis的相关信息 -->
    	<!-- Redis连接池的配置 -->
    	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    		<property name="maxTotal" value="${redis.pool.maxActive}" />
    		<property name="maxIdle" value="${redis.pool.maxIdle}" />
    		<property name="minIdle" value="${redis.pool.minIdle}" />
    		<property name="maxWaitMillis" value="${redis.pool.maxWait}" />
    		<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
    		<property name="testOnReturn" value="${redis.pool.testOnReturn}" />
    	</bean>
    	<!-- 在java中需要调用redis的地方注入jedisPool这个连接池对象 -->
    	<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
    		<constructor-arg index="0" ref="jedisPoolConfig" />
    		<constructor-arg index="1" value="${redis.hostName}" />
    		<constructor-arg index="2" value="${redis.port}" />
    		<constructor-arg index="3" value="${redis.timeout}" />
    		<!--Redis密码 -->
    		<!--<constructor-arg index="4" value="${redis.password}" /> -->
    	</bean>
    
    redis.hostName=192.168.1.238
    redis.port=6379
    redis.password=
    redis.timeout=5000
    redis.pool.maxActive=300
    redis.pool.maxIdle=250
    redis.pool.minIdle=200
    redis.pool.maxWait=3000
    redis.pool.testOnBorrow=true
    redis.pool.testOnReturn=true
    

    3. 创建一个工具类用来存放可能用到的属性等信息:

    /**用来存用户的点赞信息等属性 */
    public class RedisKey {
    	//我关注的人的列表
    	public static final String FOLLOW_USER = "follow_user";
    	//关注我的人的列表
    	public static final String FOLLOWED_USER = "followed_user";
    	//我关注的话题列表
    	public static final String FOLLOW_TOPIC = "follow_topic";
    	//我关注的问题列表
    	public static final String FOLLOW_QUESTION = "follow_question";
    	//获得收藏的次数
    	public static final String COLLECTION_COUNT = "collection_count";
    	//获得点赞的次数
    	public static final String ZAN_COUNT = "zan_count";
    }
    

    4. rides在java项目中的使用(rides存储对象和实现用户免登陆效果):

    1. 创建一个rides连接池对象Jedis,只用@Autowired
    2. 使用rides存放用户对象信息下面是一个新增用户功能的实现,用到了工具类:通常,点赞,关注人数,收藏数这些信息可以使用rides来存储
    @Service
    public class UserServiceImp extends BaseServiceImpl<User> implements UserService {
    	//注入一个redis的连接池对象
    	@Autowired
    	JedisPool jedisPool;
    	@Override
    	public void register(User user) {
    		//初始化redis中的个人信息数据
    		//集合类型可以用 11231:follow_user 112 1132  233
    		//通过连接池对象获得一个连接,相当于从连接池中拿一个连接
    		Jedis jedis =  jedisPool.getResource();//创建一个rides连接对象
    		//存关注的人等集合信息使用sadd()
    		jedis.sadd(user.getId()+":"+RedisKey.FOLLOW_USER, "3","4","5");
    		//存的集合默认null值不适合初始化
    		//存点赞次数集合,数值类型也用string,收藏次数默认值都是“0”
    		jedis.set(user.getId()+":"+RedisKey.ZAN_COUNT, "0");
    		jedis.set(user.getId()+":"+RedisKey.COLLECTION_COUNT, "0");
    	}
    }
    
    1. 将用户对象转换成gson格式的字符串存到rides中(登录的时候把对象信息存到rides中,可以将rides的key存到cookie中):
    	@Override
    	public int selectByEmailaPwdaState(User user,HttpSession httpsession,HttpServletResponse response) {
    		//登录成功后将对象存到redis中,转换成gson字符串格式,cookie从redis中获取对象
    		//通过连接池对象获得一个连接,相当于从连接池中拿一个连接
    		Jedis jedis = jedisPool.getResource();
    		Gson gson = new Gson();//创建gson对象
    		//key用随机字符串将转化成json格式的对象存入redis
    		String key = UUID.randomUUID().toString();
    		jedis.setex("SESSION:"+key, 60*60*24*3, gson.toJson(user1));
    		//登录成功后存入cookie,实现免登陆效果
    		//token授权的意思,key随机字符用来调用redis中对象字符串
    		Cookie cookie = new Cookie("token",key);//创建cookie,里面存redis的key
    		cookie.setMaxAge(60*60*24*3);//设置cookie的失效时间
    		cookie.setPath("/");//设置cookie作用域在当前项目下
    		response.addCookie(cookie);//写入cookie
    	}
    
    1. 在拦截器中通过key取出rides中的值(实现免登录效果):
    		//注入一个redis的连接池对象
    		@Autowired
    		JedisPool jedisPool;
    		
    		//通过连接池对象获得一个连接,相当于从连接池中拿一个连接
    		Jedis jedis = jedisPool.getResource();
    		//根据cookie来判断是否登录
    		//得到所有的cookie
    		Cookie[] cookies = req.getCookies();
    		for(Cookie cookie : cookies){
    			//查看cookie中有没有叫token的授权码key,指向的是redis中登录时存的user对象
    			if(cookie.getName().equals("token")){
    				//如果有取出token中的key授权码value去核对
    				String token = cookie.getValue();
    				//在redis中看该授权码对应的信息是否正确
    				String result = jedis.get("SESSION:"+token);
    				if(result==null){
    					//如果在redis中没有对应的信息跳转到登录页面
    					resp.sendRedirect("/login.jsp");
    					return false;
    				}else{
    					//不等于空说明已登录,通过
    					//因为是免登陆效果当退出的时候session已经被清空,需要在这里重新把对象存到session
    					Gson gson = new Gson();
    					User user = gson.fromJson(result, User.class);
    					req.getSession().setAttribute("user", user);
    					return true;
    				}
    			}
    		}
    
    1. 删除rides中的某个值,通过key删除某个值:
    		//清除redis,删除掉某个key
    		Jedis jedis = jedisPool.getResource();
    		jedis.del("SESSION:"+value);
    
    展开全文
  • 要使用Uber Rides Python SDK,请执行以下操作: $ pip install uber_rides 转至以获得有关安装pip的说明。 要从运行,您可以超级骑行者,然后运行: $ python setup.py install 我们建议您在设置项目环境时使用 ...
  • the magic school bus rides again s02e13_英文(en)-auto
  • Rides学习笔记

    2021-07-28 21:09:32
    Rides学习笔记 学习狂神Redis的详细笔记,个人手写,注意点赞收藏哦! 基础知识 redis默认有16个数据库,默认使用的数据库索引为0,切换数据库可以使用select,DBSIZE可以查看数据库大小 keys *查看数据库所有key ...

    Rides学习笔记

    学习狂神Redis的详细笔记,个人手写,注意点赞收藏哦!

    基础知识

    redis默认有16个数据库,默认使用的数据库索引为0,切换数据库可以使用select,DBSIZE可以查看数据库大小

    keys *查看数据库所有key

    清除当前数据库 flushdb,清除全部数据库的内容flushall

    redis是单线程的,官方表示,Redis是基于内存操作的

    五大基本数据类型

    redis-key

    redis中key区分大小写

    redis-cli -p 6379	#连接redis
    

    EXISTS [KEY] 判断当前的key是否存在

    move [key] 1移除当前的key

    EXPIRE [KEY] X 设置当前key过期时间,单位:X秒,类似cookie

    ttl [key] 查看当前key的过期时间

    type [key]查看key对应value的类型

    APPEND [KEY] “*” 追加字符串如多当前key不存在就相当于set key

    127.0.0.1:6379> keys *
    1) "k2"
    2) "mysay"
    3) "views"
    4) "k1"
    5) "k3"
    6) "say2"
    7) "say"
    127.0.0.1:6379> flushdb	#清空数据库
    OK
    127.0.0.1:6379> keys *
    (empty array)
    

    增长

    #i++操作
    127.0.0.1:6379> set views 0
    OK
    127.0.0.1:6379> incr views 	#自增1
    (integer) 1
    127.0.0.1:6379> incr views
    (integer) 2
    127.0.0.1:6379> incr views
    (integer) 3
    127.0.0.1:6379> decr views	#自减1
    (integer) 2
    127.0.0.1:6379> decr views
    (integer) 1
    127.0.0.1:6379> incrby views 10	#设置步长
    (integer) 11
    127.0.0.1:6379> decrby views 5
    (integer) 6
    
    

    String

    #字符范围 rang
    127.0.0.1:6379> set say "hello,redis"
    OK
    127.0.0.1:6379> get say
    "hello,redis"
    127.0.0.1:6379> GETRANGE say 0 3 #截取字符串[0,3]
    "hell"
    127.0.0.1:6379> GETRANGE say 0 -1 #截取全部字符串
    "hello,redis"
    
    127.0.0.1:6379> set say2 qwertyu
    OK
    127.0.0.1:6379> get say2
    "qwertyu"
    127.0.0.1:6379> setrange say2 1 aa	#替换指定位置开始的字符串
    (integer) 7
    127.0.0.1:6379> get say2
    "qaartyu"
    127.0.0.1:6379> setrange say2 0 xx
    (integer) 7
    127.0.0.1:6379> get say2
    "xxartyu"
    
    
    
    
    #####################################################################################
    #	setex (set with expire) 设置过期时间
    #	setnx (set if not exist) 不存在设置(分布式锁中会常常用)
    
    127.0.0.1:6379> setex say3 30 "hello"	#设置say3 的值为hello,30秒后过期
    OK
    127.0.0.1:6379> ttl say3	#查看剩余过期秒数
    (integer) 20
    127.0.0.1:6379> ttl say3
    (integer) 17
    127.0.0.1:6379> get say3
    "hello"
    127.0.0.1:6379> get say3
    "hello"
    127.0.0.1:6379> ttl say3
    (integer) 4
    127.0.0.1:6379> setnx mysay "redis"	#如果mysay不存在,创建mysay
    (integer) 1	#1表示成功
    127.0.0.1:6379> keys *
    1) "say2"
    2) "mysay"
    3) "views"
    4) "say"
    127.0.0.1:6379> setnx mysay "MongoDB"	#如果mysay存在,创建失败!
    (integer) 0	#0表示失败
    127.0.0.1:6379> get mysay
    "redis"
    ###################################################################################
    
    127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3	#同时设置多个键值
    OK
    127.0.0.1:6379> keys *
    1) "k3"
    2) "k2"
    3) "k1"
    127.0.0.1:6379> mget k1 k2 k3	#同时获取多个值
    1) "v1"
    2) "v2"
    3) "v3"
    127.0.0.1:6379> msetnx k1 v1 k4 v4	#msetnx是原子性的操作,要么一起成功,要么一起失败。	
    (integer) 0
    127.0.0.1:6379> keys *
    1) "k3"
    2) "k2"
    3) "k1"
    
    #####################################################################################
    
    set user:1{name:zhangsan,age:12} #设置一个user:1对象 值为json字符来保存一个对象
    
    #这里的key是一个巧妙的设计:user:{id}:{filed}
    
    127.0.0.1:6379> mset user:1:name zhangsan user:1:age 12
    OK
    127.0.0.1:6379> mget user:1:name user:1:age
    1) "zhangsan"
    2) "12"
    
    #####################################################################################
    getset	#先get后set
    
    127.0.0.1:6379> getset db mongodb	#如果不存在值,则返回nil,设置值
    (nil)
    127.0.0.1:6379> get db
    "mongodb"
    127.0.0.1:6379> getset db redis	#如果存在值,则返回值,设置新值
    "mongodb"
    127.0.0.1:6379> get db
    "redis"
    
    
    #####################################################################################
    

    List

    在redis中,我们可以将list玩成栈、队列、阻塞队列

    所有的list命令都是用l开头的

    #####################################################################################
    
    127.0.0.1:6379> lpush list one	#将一个值或者多个值插入到列表的头部(上,左)
    (integer) 1
    127.0.0.1:6379> lpush list two
    (integer) 2
    127.0.0.1:6379> lpush list three
    (integer) 3
    127.0.0.1:6379> lrange list 0 -1	#获取list中的值
    1) "three"	
    2) "two"
    3) "one"
    127.0.0.1:6379> lrange list 0 1	#获取指定区间的值
    1) "three"
    2) "two"
    127.0.0.1:6379> rpush list right	##将一个值或者多个值插入到列表的尾部(下,右)
    (integer) 4
    127.0.0.1:6379> lrange list 0 -1
    1) "three"
    2) "two"
    3) "one"
    4) "right"
    
    #####################################################################################
    
    lpop
    rpop
    
    127.0.0.1:6379> lpop list	#移除队首的第一个
    "three"
    127.0.0.1:6379> lrange list 0 -1
    1) "two"
    2) "one"
    3) "right"
    127.0.0.1:6379> rpop list	#移除队尾的第一个
    "right"
    127.0.0.1:6379> lrange list 0 -1
    1) "two"
    2) "one"
    
    #####################################################################################
    lindex
    
    127.0.0.1:6379> lindex list 0	#通过下标获取某一个值
    "two"
    127.0.0.1:6379> lindex list 1	
    "one"
    
    127.0.0.1:6379> lrange list 0 -1
    1) "two"
    2) "one"
    127.0.0.1:6379> llen list	#返回列表的长度
    (integer) 2
    
    #####################################################################################
    
    移除指定的值
    
        127.0.0.1:6379> lrange list 0 -1	#将list中的值全部取出
    1) "two"
    2) "one"
    127.0.0.1:6379> llen list	#查看list长度
    (integer) 2
    127.0.0.1:6379> lpush list three	#向list中添加值
    (integer) 3
    127.0.0.1:6379> lpush list three
    (integer) 4
        127.0.0.1:6379> lrange list 0 -1	#将list中的值全部取出
    1) "three"
    2) "three"
    3) "two"
    4) "one"
    127.0.0.1:6379> lrem list 1 three	#从list中移除一个值从上至下,精确匹配
    (integer) 1
    127.0.0.1:6379> lrange list 0 -1
    1) "three"
    2) "two"
    3) "one"
    127.0.0.1:6379> lpush list three
    (integer) 4
    127.0.0.1:6379> lrange list 0 -1
    1) "three"
    2) "three"
    3) "two"
    4) "one"
    127.0.0.1:6379> lrem list 2 three	#从list中移除两个值从上至下
    (integer) 2
    127.0.0.1:6379> lrange list 0 -1
    1) "two"
    2) "one"
    
    #####################################################################################
    截取
    127.0.0.1:6379> lpush mylist "hello" "redis" "MongoDB"
    (integer) 3
    127.0.0.1:6379> keys *
    1) "mylist"
    127.0.0.1:6379> lrange mylist 0 -1
    1) "MongoDB"
    2) "redis"
    3) "hello"
    127.0.0.1:6379> ltrim mylist 1 2	#通过下标截取指定区间长度的值,该list集合只剩下截取的元素
    OK
    127.0.0.1:6379> lrange mylist 0 -1
    1) "redis"
    2) "hello"
    
    #####################################################################################
    
    LSET
    
    127.0.0.1:6379> lpush mylist "hello" "redis" "MongoDB"
    (integer) 3
    127.0.0.1:6379> lrange mylist 0 -1
    1) "MongoDB"
    2) "redis"
    3) "hello"
    #组合
    rpoplpush [list] [list]
    rpoprpush [list] [list] 
    lpoplpush [list] [list] 
    lpoprpush [list] [list]
    
    127.0.0.1:6379> rpoplpush mylist otherlist	#从mylist中移除值到otherlist(如果otherlist不存在则创建)
    "hello"
    127.0.0.1:6379> lrange mylist 0 -1	
    1) "MongoDB"
    2) "redis"
    127.0.0.1:6379> lrange otherlist 0 -1
    1) "hello"
    127.0.0.1:6379> keys *
    1) "mylist"
    2) "otherlist"
    127.0.0.1:6379> lset test 0 hello	#list将下标为0 的值设置为hello,如果list集合不存在则报错
    (error) ERR no such key
    127.0.0.1:6379> lset otherlist 0 xiaomi	#list将下标为X 的值设置为*,如果list集合存在则将原有值设置为*相当于更新操作
    OK
    127.0.0.1:6379> lrange otherlist 0 -1
    1) "xiaomi"
    127.0.0.1:6379> llen otherlist
    (integer) 1
    127.0.0.1:6379> lset otherlist 1 xiaomi
    (error) ERR index out of range
    
    #####################################################################################
    #插入
    linsert
    
    127.0.0.1:6379>  LRANGE mylist 0 -1	#将mylist中的值全部取出
    1) "MongoDB"
    2) "redis"
    127.0.0.1:6379> linsert mylist before redis hello	#在redis前插入hello
    (integer) 3
    127.0.0.1:6379>  LRANGE mylist 0 -1	#将mylist中的值全部取出
    1) "MongoDB"
    2) "hello"
    3) "redis"
    127.0.0.1:6379> linsert mylist after mongodb nb	#在MongoDB后插入nb,注意区分字段大小写
    (integer) -1
    127.0.0.1:6379>  LRANGE mylist 0 -1
    1) "MongoDB"
    2) "hello"
    3) "redis"
    127.0.0.1:6379> linsert mylist after MongoDB nb
    (integer) 4
    127.0.0.1:6379>  LRANGE mylist 0 -1
    1) "MongoDB"
    2) "nb"
    3) "hello"
    4) "redis"
    127.0.0.1:6379> lpush mylist hello	#向集合中添加hello使得集合中有两个相同的值测试插入时插入到哪一值前或后
    (integer) 5
    127.0.0.1:6379> linsert mylist after hello lpx	#向hello后插入lpx
    (integer) 6
    127.0.0.1:6379>  LRANGE mylist 0 -1	#有两个相同value时使用linsert插入时选择的是顶端的value
    1) "hello"
    2) "lpx"
    3) "MongoDB"
    4) "nb"
    5) "hello"
    6) "redis"
    
    
    #####################################################################################
    

    小结

    本质是一个链表,Node前后都可以插入,两边插入的效率比中间高一些。
    应用场景:实现消息队列(左进右出,或反之)、栈(左进左出,或反之)。

    set

    #####################################################################################
    
    127.0.0.1:6379> sadd myset hello redis MongoDB
    (integer) 3
    127.0.0.1:6379> smembers myset	#查看指定set的所有值
    1) "hello"
    2) "MongoDB"
    3) "redis"
    127.0.0.1:6379> sismember myset hello	#判断某一个值是不是在set集合中
    (integer) 1
    127.0.0.1:6379> sismember myset word
    (integer) 0
    
    #####################################################################################
    
    127.0.0.1:6379> scard myset
    (integer) 3
    
    #####################################################################################
    
    127.0.0.1:6379> sadd myset lpx	
    (integer) 1
    127.0.0.1:6379> smembers myset
    1) "lpx"
    2) "hello"
    3) "MongoDB"
    4) "redis"
    127.0.0.1:6379> srem myset lpx	#移除set集合中指定的元素
    (integer) 1
    127.0.0.1:6379> smembers myset
    1) "hello"
    2) "MongoDB"
    3) "redis"
    
    #####################################################################################
    
    set无序不重复集合
    
    127.0.0.1:6379> srandmember myset	#随机抽选出一个元素
    "redis"
    127.0.0.1:6379> srandmember myset
    "hello"
    127.0.0.1:6379> srandmember myset 2	#随机抽选出两个个元素
    1) "hello"
    2) "MongoDB"
    127.0.0.1:6379> srandmember myset 2
    1) "redis"
    2) "MongoDB"
    127.0.0.1:6379> srandmember myset 2
    1) "hello"
    2) "MongoDB"
    127.0.0.1:6379> srandmember myset 2
    1) "hello"
    2) "redis"
    
    ######################################################################################
    
    删除指定key,随机y
    
    127.0.0.1:6379> smembers myset
    1) "hello"
    2) "MongoDB"
    3) "redis"
    127.0.0.1:6379> spop myset	#随机删除set集合中的一些元素
    "MongoDB"
    127.0.0.1:6379> smembers myset
    1) "hello"
    2) "redis"
    ######################################################################################
    
    移动
    127.0.0.1:6379> smembers myset
    1) "hello"
    2) "redis"
    127.0.0.1:6379> smove myset myset2 hello	#将一个集合中的元素移动到另一个集合中
    (integer) 1
    127.0.0.1:6379> smembers myset2
    1) "hello"
    
    ######################################################################################
    
    微博,B站,共同关注!(并集)
    数字集合类
    -差集
    -交集
    -并集
    
    127.0.0.1:6379> sadd myset a b c
    (integer) 3
    127.0.0.1:6379> sadd myset2 c d e 
    (integer) 3
    127.0.0.1:6379> smembers myset
    1) "c"
    2) "a"
    3) "b"
    127.0.0.1:6379> smembers myset2
    1) "c"
    2) "e"
    3) "d"
    127.0.0.1:6379> sdiff myset myset2	#myset与myset2差集
    1) "a"
    2) "b"
    127.0.0.1:6379> sdiff myset2 myset	#myset2与myset差集
    1) "d"
    2) "e"
    127.0.0.1:6379> sinter myset myset2	#交集	共同好友可以这样实现
    1) "c"
    127.0.0.1:6379> sunion myset myset2	#并集
    1) "c"
    2) "e"
    3) "a"
    4) "b"
    5) "d"
    
    

    小结

    微博将所有关注的人放在一个set集合中,将他的粉丝也放在一个集合中!

    共同关注、共同爱好、推荐好友

    Hash(哈希)

    Map集合,key-map!这个值是一个map集合!本质和String类型没有太大区别 ,还是一个简单的key-value

    ######################################################################################
    
    127.0.0.1:6379> hset myhash name lpx	#set一个具体的key-value
    (integer) 1
    127.0.0.1:6379> hget myhash lpx		#获取某个值
    (nil)
    127.0.0.1:6379> hget myhash name
    "lpx"
    127.0.0.1:6379> hmset myhash age 18 name liu	##set多个key-value
    OK
    127.0.0.1:6379> hmget myhash age name	#获取多个值
    1) "18"
    2) "liu"
    127.0.0.1:6379> hgetall myhash	#获取全部值
    1) "name"
    2) "liu"
    3) "age"
    4) "18"
    
    ######################################################################################
    127.0.0.1:6379> hgetall myhash
    1) "name"
    2) "liu"
    3) "age"
    4) "18"
    5) "sex"
    6) "man"
    127.0.0.1:6379> hdel myhash sex	#删除指定hash表的指定key字段,对应的value值也就对应删除了
    (integer) 1
    127.0.0.1:6379> hgetall myhash
    1) "name"
    2) "liu"
    3) "age"
    4) "18"
    
    ######################################################################################
    
    127.0.0.1:6379> hgetall myhash
    1) "name"
    2) "liu"
    3) "age"
    4) "18"
    127.0.0.1:6379> hlen myhash	#获取某个hash表的字段数
    (integer) 2
    127.0.0.1:6379> hexists myhash name	#判断某个hash表的某个字段是否存在
    (integer) 1
    
    ######################################################################################
    
    #只获得所有field
    #只获得所有value
    
        127.0.0.1:6379> hkeys myhash	#只获得所有field
    1) "name"
    2) "age"
    127.0.0.1:6379> hvals myhash	#只获得所有value
    1) "liu"
    2) "18"
    
    ######################################################################################
    
    incr decr
    
    127.0.0.1:6379> hset myhash num 1
    (integer) 1
    127.0.0.1:6379> hgetall myhash
    1) "name"
    2) "liu"
    3) "age"
    4) "18"
    5) "num"
    6) "1"
    127.0.0.1:6379> hincrby myhash num 1	#自增1
    (integer) 2
    127.0.0.1:6379> hincrby myhash num -1	#自增-1
    (integer) 1
    127.0.0.1:6379> hsetnx myhash birthday 2021-02-06
    (integer) 1
    127.0.0.1:6379> hgetall myhash
    1) "name"
    2) "liu"
    3) "age"
    4) "18"
    5) "num"
    6) "1"
    7) "birthday"
    8) "2021-02-06"
    127.0.0.1:6379> hsetnx myhash birthday 2021-02-06	#不存在创建
    (integer) 0
    127.0.0.1:6379> hsetnx myhash birthday 2021-02-07	#已存返回0,不操作
    0
    (integer) 0
    ######################################################################################
    

    小结

    hash变更的数据user name age ,尤其是用户信息之类的,经常变动的信息

    hash更适合对象的存储,string更加适合字符串的存储

    Zset(有序集合)

    ######################################################################################
    127.0.0.1:6379> zadd myset 1 one 2 two	#添加多个值
    (integer) 2
    127.0.0.1:6379> zadd myset 3 three 4 four
    (integer) 2
    127.0.0.1:6379> zrange myset 0 -1
    1) "one"
    2) "two"
    3) "three"
    4) "four"
    ######################################################################################
    
    #排序
    127.0.0.1:6379> zadd salary 2500 xiaohong	#添加四个元素
    (integer) 1
    127.0.0.1:6379> zadd salary 2500 zhangsan
    (integer) 1
    127.0.0.1:6379> zadd salary 5000 lisi
    (integer) 1
    127.0.0.1:6379> zadd salary 3500 wangwu
    (integer) 1
    127.0.0.1:6379> zrangebyscore salary -inf +inf	#从低到高排序key做排序
    1) "xiaohong"
    2) "zhangsan"
    3) "wangwu"
    4) "lisi"
    127.0.0.1:6379> zrangebyscore salary 0 +inf		#从低到高排序key做排序
    1) "xiaohong"
    2) "zhangsan"
    3) "wangwu"
    4) "lisi"
    127.0.0.1:6379> zrangebyscore salary -inf +inf withscores	#从低到高排序,显示所有元素及值
    1) "xiaohong"
    2) "2500"
    3) "zhangsan"
    4) "2500"
    5) "wangwu"
    6) "3500"
    7) "lisi"
    8) "5000"
    127.0.0.1:6379> zrangebyscore salary 3500 5000 withscores	#指定区间从低到高排序key做排序
    1) "wangwu"
    2) "3500"
    3) "lisi"
    4) "5000"
    #从大到小排序
    127.0.0.1:6379> zrevrange salary 0 -1
    1) "lisi"
    2) "wangwu"
    3) "zhangsan"
    4) "xiaohong"
    127.0.0.1:6379> zrevrange salary 0 -1 withscores
    1) "lisi"
    2) "5000"
    3) "wangwu"
    4) "3500"
    5) "zhangsan"
    6) "2500"
    7) "xiaohong"
    8) "2500"
    ######################################################################################
    
    #移除
    
    127.0.0.1:6379> zrevrange salary 0 -1 withscores
    1) "lisi"
    2) "5000"
    3) "wangwu"
    4) "3500"
    5) "zhangsan"
    6) "2500"
    7) "xiaohong"
    8) "2500"
    127.0.0.1:6379> zrem salary xiaohong	#移除指定元素
    (integer) 1
    127.0.0.1:6379> zrevrange salary 0 -1 withscores
    1) "lisi"
    2) "5000"
    3) "wangwu"
    4) "3500"
    5) "zhangsan"
    6) "2500"
    ######################################################################################
    
    #统计区间中元素数量
    
    127.0.0.1:6379> zrevrange salary 0 -1 withscores
    1) "lisi"
    2) "5000"
    3) "wangwu"
    4) "3500"
    5) "zhangsan"
    6) "2500"
    127.0.0.1:6379> zcount salary 2500 4000
    (integer) 2
    127.0.0.1:6379> zcount salary 2500 5000
    (integer) 3
    127.0.0.1:6379> zcount salary 3000 5000
    (integer) 2
    
    

    三种特殊数据类型

    geospatial地理位置

    朋友的定位,附近的人,打车距离计算

    ######################################################################################
    #geoadd
    #两级是无法直接添加的,我们一般会下载城市数据,直接通过java程序一次性导入
    #参数 key 值(纬度 经度 名称)
    127.0.0.1:6379> geoadd china:city 115.07168 34.44539 suixian
    (integer) 1
    127.0.0.1:6379> geoadd china:city 115.65338 34.38804 suiyangqu
    
    (integer) 1
    127.0.0.1:6379> geoadd china:city 114.35708 36.09046 wenfengqu
    
    (integer) 1
    127.0.0.1:6379> geoadd china:city 113.81558 36.07804 linzhoushi 115.14621 34.64931 minquanxian
    (integer) 2
    
    ######################################################################################
    
    #获得当前定位:坐标值
    
    127.0.0.1:6379> geopos china:city suixian	#获取指定的经度和纬度
    1) 1) "115.07167786359786987"
       2) "34.44538914978334532"
    
    
    ######################################################################################
    
    #geodist
    
    127.0.0.1:6379> geodist china:city suixian suiyangqu	#查询睢县到睢阳区的距离默认m
    "53754.2987"
    127.0.0.1:6379> geodist china:city suixian suiyangqu km	#查询睢县到睢阳区的距离 km
    "53.7543"
    
    ######################################################################################
    
    #georadius
    
    127.0.0.1:6379> georadius china:city 115.07168 34.44539 100 km	#查询100km(半径)以内的位置
    
    1) "suixian"
    2) "minquanxian"
    3) "suiyangqu"
    
    127.0.0.1:6379> georadius china:city 115.07168 34.44539 100 km withcoord withdist withhash count 2	#查询100km以内的位置,限定数量为2
    1) 1) "suixian"
       2) "0.0002"						#距离 withdist
       3) (integer) 4064341297318991	#withhash
       4) 1) "115.07167786359786987"	#显示他人的定位信息 withcoord
          2) "34.44538914978334532"
    2) 1) "minquanxian"
       2) "23.6867"	#距离
       3) (integer) 4065078118317270
       4) 1) "115.14621108770370483"
          2) "34.64931000177332265"
    
    
    ######################################################################################
    
    #GEORADIUSBYMEMBER
    #找出位于指定元素周围的其它元素
    127.0.0.1:6379> GEORADIUSBYMEMBER china:city suixian 100 km	#
    1) "suixian"
    2) "minquanxian"
    3) "suiyangqu"
    
    ######################################################################################
    
    #geohash
    #该命令返回11个字符串的geohash字符串
    127.0.0.1:6379> geohash china:city suixian
    1) "ww1gfw8dum0"	#将二维的字符串转换为一维的字符串,如果两个字符串越接近,距离就越近
    
    
    ######################################################################################
    
    #GEO底层原理其实是Zset,我们可以使用zset命令来操作geo
    
    127.0.0.1:6379> zrange china:city 0 -1	#查看地图中全部元素
    1) "suixian"
    2) "suiyangqu"
    3) "minquanxian"
    4) "linzhoushi"
    5) "wenfengqu"
    127.0.0.1:6379> zrem china:city minquanxian	#移除地图中某一个元素
    (integer) 1
    127.0.0.1:6379> zrange china:city 0 -1
    1) "suixian"
    2) "suiyangqu"
    3) "linzhoushi"
    4) "wenfengqu"
    
    
    ######################################################################################
    

    hyperloglog

    redis 在 2.8.9 版本添加了 HyperLogLog 结构。

    Redis HyperLogLog 是用来做基数统计的算法

    什么是基数?

    比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

    一般用来网页的访问量uv(一个人访问网站多次,但还是算作一个人)

    传统的方式,set保存用户的id.然后就可以统计set中元素的数量作为标准

    HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

    测试使用

    ######################################################################################
    
    127.0.0.1:6379> pfadd mykey a b c d e f g h i j k l m n	#创建一组元素
    (integer) 1
    127.0.0.1:6379> pfcount mykey	#统计元素基数
    (integer) 14
    127.0.0.1:6379> pfadd mykey2 a q w e r t z x c v b	#创建一组元素
    (integer) 1
    127.0.0.1:6379> pfcount mykey2
    (integer) 11
    127.0.0.1:6379> pfmerge mykey3 mykey mykey2	#将两组元素并到第三组
    OK
    127.0.0.1:6379> pfcount mykey3
    (integer) 20
    
    ######################################################################################
    

    Bitmaps 位图

    位存储

    Bitmaps是一种特殊的“数据结构”,实质上是一个字符串,操作单元是位。二进制位来操作进行记录,就只有0和1两个状态可用

    统计疫情感染人数:0 0 0 0 0 0 1 0 0 …

    统计用户信息,活跃,不活跃,登录,未登录,打卡等两个状态的都可以使用bitmaps

    测试

    使用bitmap来记录周一到周日的打卡

    周一:1、周二:2、周三:3、周四:4、周五:5、周六:6、周日:0、

    打卡状态:

    ​ -0:未打开

    ​ -1:已打卡

    127.0.0.1:6379> setbit sign 0 1
    (integer) 0
    127.0.0.1:6379> setbit sign 1 0
    (integer) 0
    127.0.0.1:6379> setbit sign 2 0
    (integer) 0
    127.0.0.1:6379> setbit sign 3 0
    (integer) 0
    127.0.0.1:6379> setbit sign 4 0
    (integer) 0
    127.0.0.1:6379> setbit sign 5 0
    (integer) 0
    127.0.0.1:6379> setbit sign 6 0
    (integer) 0
    
    

    查看某一天是否已经打卡

    127.0.0.1:6379> getbit sign 3
    (integer) 0
    127.0.0.1:6379> getbit sign 0
    (integer) 1
    
    

    统计打卡天数

    127.0.0.1:6379> bitcount sign	#统计这周打卡记录
    (integer) 1
    

    事务

    redis 事务本质:一组命令的集合,一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行

    一次性、顺序性、排他性,执行一系列的命令

    ------队列 set set set...执行-----
    

    redis事务没有隔离级别的概念

    所有的命令在事务中并没有直接被执行,只有发起执行命令的时候才会执行!Exec

    redis单条命令是保证原子性的,但是事务是不保证原子性的

    redis的事务:

    ​ -开启事务(multi)

    ​ -命令入队 (…)

    ​ -执行事务

    锁:Redis可以实现乐观锁,watch

    正常执行事务

    127.0.0.1:6379> multi	#开启事务
    OK
    # 命令入队
    127.0.0.1:6379(TX)> set k1 v1
    QUEUED
    127.0.0.1:6379(TX)> set k2 v2
    QUEUED
    127.0.0.1:6379(TX)> get k2
    QUEUED
    127.0.0.1:6379(TX)> set k3 v3
    QUEUED
    
    #	执行事务
    127.0.0.1:6379(TX)> exec
    1) OK
    2) OK
    3) "v2"
    4) OK
    
    

    放弃事务

    127.0.0.1:6379> multi	#开启事务
    OK
    127.0.0.1:6379(TX)> set k1 v1
    QUEUED
    127.0.0.1:6379(TX)> set k2 v2
    QUEUED
    127.0.0.1:6379(TX)> set k3 v3
    QUEUED
    127.0.0.1:6379(TX)> set k4 v4
    QUEUED
    127.0.0.1:6379(TX)> discard	#取消事务,事务中的命令都不会执行
    OK
    127.0.0.1:6379> get k4
    (nil)
    
    

    编译时异常(代码有问题),事务中所有的命令都不会被执行

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> set k1 v1
    QUEUED
    127.0.0.1:6379(TX)> set k2 v2
    QUEUED
    127.0.0.1:6379(TX)> set k3 v3
    QUEUED
    127.0.0.1:6379(TX)> getset k3	#错误命令
    (error) ERR wrong number of arguments for 'getset' command
    127.0.0.1:6379(TX)> set k4 v4
    QUEUED
    127.0.0.1:6379(TX)> exec	#执行事务
    (error) EXECABORT Transaction discarded because of previous errors.
    127.0.0.1:6379> get k4		#所有的命令都不会执行
    (nil)
    
    

    运行时异常(1/0),如果事务队列中存在语法性,那么执行命令时,其他命令时可以正常执行的,错误命令抛异常

    127.0.0.1:6379> set k1 "v1"
    OK
    127.0.0.1:6379> get k1
    "v1"
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> incr k1	#会执行的时候失败
    QUEUED
    127.0.0.1:6379(TX)> set k2 v2
    QUEUED
    127.0.0.1:6379(TX)> get k2
    QUEUED
    127.0.0.1:6379(TX)> exec
    1) (error) ERR value is not an integer or out of range	#虽然这条命令报错了,但是依旧正常执行成功了
    2) OK
    3) "v2"
    

    监控 watch

    悲观锁

    ​ -很悲观,认为什么时候都会出现问题,无论做什么都加锁

    乐观锁

    ​ -很乐观,认为什么时候都不会出现问题,所以不会加锁,更新数据的时候去判断一下,在此器件是否有人修改过这个数据

    ​ -获取version

    ​ -更新的时候比较version

    redis监视测试

    正常执行成功

    127.0.0.1:6379> set money 100
    OK
    127.0.0.1:6379> set out 0
    OK
    127.0.0.1:6379> watch money		#监控money对象
    OK
    127.0.0.1:6379> multi			#事务正常结束,数据期间没有发生变动,这个时候就正常执行成功
    OK
    127.0.0.1:6379(TX)> decrby money 30
    QUEUED
    127.0.0.1:6379(TX)> incrby out 30
    QUEUED
    127.0.0.1:6379(TX)> exec
    1) (integer) 70
    2) (integer) 30
    
    

    测试多线程修改值,使用watch当作redis的乐观锁操作

    127.0.0.1:6379> watch money
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> decrby money 10
    QUEUED
    127.0.0.1:6379(TX)> incrby out 10
    QUEUED
    127.0.0.1:6379(TX)> exec	#执行之前另外一个线程修改了监控的值,这时候就会导致事务执行失败
    (nil)
    
    #-----------------------另一线程-------------------------
    127.0.0.1:6379> clear
    127.0.0.1:6379> set money 200 
    OK
    
    
    ###########################################################################################
    
    127.0.0.1:6379(TX)> exec
    (nil)
    127.0.0.1:6379> unwatch		#事务执行失败,先解锁,解除监控
    OK
    127.0.0.1:6379> watch money	#获取新的值,再次监视
    
    

    Jedis

    Jedis是Redis官方推荐的Java连接开发工具。

    1、导入依赖

    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.6.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.76</version>
    </dependency>
    

    2、编码测试:

    ​ -连接数据库

    ​ -操作命令

    ​ -断开连接

    Springboot整合Redis

    springboot操作数据:spring-data jpa jdbc mongodb redis

    SpringData也是和spring boot齐名的项目

    说明:在spring boot2.x之后,原来使用的jedis被替换为了lettuce

    jedis:采用的是直连的多个线程操作是不安全的,使用jedis pool连接池,更像BIO

    lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况,可以减少线程数量,更像NIO

    源码分析:

    	@Bean
    	@ConditionalOnMissingBean(name = "redisTemplate")	//可以自定义redisTemplate来替换这个默认的
    	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
    			throws UnknownHostException {
            
            //默认的RedisTemplate没有过多设置,redis都是需要序列化的
            //两个泛型都是Object类型,后使用需要强制转换<String,Object>
    		RedisTemplate<Object, Object> template = new RedisTemplate<>();
    		template.setConnectionFactory(redisConnectionFactory);
    		return template;
    	}
    
    	@Bean
    	@ConditionalOnMissingBean	//由于String是redis中最常使用的类型,所以单独提出一个bean
    	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
    			throws UnknownHostException {
    		StringRedisTemplate template = new StringRedisTemplate();
    		template.setConnectionFactory(redisConnectionFactory);
    		return template;
    	}
    

    整合测试

    1、导入依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    

    2、配置连接

    #配置redis
    spring.redis.host=127.0.0.1
    spring.redis.port=6379
    

    3、测试

    User user = new User("lpx",18);
    String jsonUser = new ObjectMapper().writeValueAsString(user);
    redisTemplate.opsForValue().set("user",jsonUser);
    

    编写一个自己的RedisTemplate

    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
    
            //为了方便,一般直接使用<String, Object>的泛型
            RedisTemplate<String, Object> template = new RedisTemplate<>();
    
            //连接默认的
            template.setConnectionFactory(redisConnectionFactory);
    
    
            //Jackson序列化配置
            Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    
            //指定序列化输入的类型 enableDefaultTyping已过期官方推荐使用activateDefaultTyping
    //        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance);
            jsonRedisSerializer.setObjectMapper(objectMapper);
    
            //String的序列化
            StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    
    
    //        key使用String的序列化方式
            template.setKeySerializer(stringRedisSerializer);
    
    //        hash的key也采用String的序列化
            template.setHashKeySerializer(stringRedisSerializer);
    
    //        value序列化方式采用Jackson
            template.setValueSerializer(jsonRedisSerializer);
    
    //        hash的value序列化方式采用jackson
            template.setHashKeySerializer(jsonRedisSerializer);
            template.afterPropertiesSet();
    
            return template;
        }
    }
    

    redis.config详解

    单位

    # Redis configuration file example.
    #
    # Note that in order to read the configuration file, Redis must be
    # started with the file path as first argument:
    #
    # ./redis-server /path/to/redis.conf
    
    # Note on units: when memory size is needed, it is possible to specify
    # it in the usual form of 1k 5GB 4M and so forth:
    #
    # 1k => 1000 bytes
    # 1kb => 1024 bytes
    # 1m => 1000000 bytes
    # 1mb => 1024*1024 bytes
    # 1g => 1000000000 bytes
    # 1gb => 1024*1024*1024 bytes
    #配置文件对大小写不敏感
    # units are case insensitive so 1GB 1Gb 1gB are all the same.
    

    包含

    可以将多个配置文件都配置过来

    ################################## INCLUDES ###################################
    
    # Include one or more other config files here.  This is useful if you
    # have a standard template that goes to all Redis servers but also need
    # to customize a few per-server settings.  Include files can include
    # other files, so use this wisely.
    #
    # Notice option "include" won't be rewritten by command "CONFIG REWRITE"
    # from admin or Redis Sentinel. Since Redis always uses the last processed
    # line as value of a configuration directive, you'd better put includes
    # at the beginning of this file to avoid overwriting config change at runtime.
    #
    # If instead you are interested in using includes to override configuration
    # options, it is better to use include as the last line.
    #
    # include /path/to/local.conf
    # include /path/to/other.conf
    

    网络

    bind 127.0.0.1
    protected-mode yes
    port 6379
    
    

    通用 GENERAL

    daemonize yes #以守护进程的方式运行
    
    pidfile /www/server/redis/redis.pid #如果以后台方式运行,我们就需要指定一个pid文件
    
    
    #日志
    # Specify the server verbosity level.
    # This can be one of:
    # debug (a lot of information, useful for development/testing)
    # verbose (many rarely useful info, but not a mess like the debug level)
    # notice (moderately verbose, what you want in production probably)
    # warning (only very important / critical messages are logged)
    loglevel notice
    
    # Specify the log file name. Also the empty string can be used to force
    # Redis to log on the standard output. Note that if you use standard
    # output for logging but daemonize, logs will be sent to /dev/null
    logfile "/www/server/redis/redis.log"	#日志生成文件名
    
    databases 16	#默认数据库的数量
    
    always-show-logo yes	#是否总是显示自己的logo
    

    快照 SNAPSHOTTING

    持久化,在规定的时间内。执行多少次操作,则会持久化到 .rdb / .aof 文件

    redis是内存数据库,如果没有持久化,那么数据断电即失!

    #如果900秒内,如果至少有1个key进行了修改,我们即进行持久化操作
    save 900 1
    #如果300秒内,如果至少10个key进行了修改,我们即进行持久化操作
    save 300 10
    #如果60秒内,如果至少10000个key进行了修改,我们即进行持久化操作
    save 60 10000
    
    stop-writes-on-bgsave-error yes	#持久化数据出问题了就拒绝新的写入
    
    rdbcompression yes	#是否压缩rdb文件
    
    rdbchecksum yes	#保存rdb文件时进行错误的检查校验
    
    dir /www/server/redis/	#rdb保存的目录
    
    

    复制 REPLICATION,关于主从复制

    
    

    安全 SECURITY

    可以设置密码,默认没有密码

    # requirepass foobared
    
    #获取redis密码
    config get requirepass
    #命令设置密码
    config set requirepass "******"
    #验证密码
    auth ******
    

    限制客户端 CLIENTS

    # maxclients 10000	#最大客户端的数量
    
    # maxmemory <bytes>	#配置最大内存容量
    
    
    # maxmemory-policy noeviction	#内存达到上限之后的处理策略
        # maxmemory-policy 六种方式
        # 1、volatile-lru:只对设置了过期时间的key进行LRU(默认值) 
        # 2、allkeys-lru : 删除lru算法的key   
        # 3、volatile-random:随机删除即将过期key   
        # 4、allkeys-random:随机删除   
        # 5、volatile-ttl : 删除即将过期的   
        # 6、noeviction : 永不过期,返回错误
    

    APPEND ONLY 模式

    appendonly no	#默认 是不开启aof模式的,默认使用的是rdb方式持久化的,在大部分所有的情况下,rdb完全够用
    
    # The name of the append only file (default: "appendonly.aof")	
    
    appendfilename "appendonly.aof"	#持久化的文件的名字
    
    
    # appendfsync always	#每次修改都会写入,消耗性能
    appendfsync everysec	#每秒都执行一次 sync,可能会丢失这1s的数据
    # appendfsync no		#不执行sync,这个时候操作系统自己同步数据,速度最快
    
    

    Redis持久化

    redis是内存数据库,如果不将内存中的数据库状态保存到磁盘上,呢么一旦服务器进程退出,服务器中的数据库状态也会消失,所以redis提供了持久化功能

    RDB(Redis DataBase)

    什么是RDB

    在这里插入图片描述

    RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。

    也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中

    默认的文件名为dump.rdb,恢复时是将快照文件直接读到内存里

    redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件,整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那么RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据库可能丢失。

    触发机制

    #   save ""
    
    save 900 1
    save 300 10
    save 60 10000
    

    1、save规则满足的情况下,会自动触发rdb规则

    2、执行flushall也会触发rdb规则

    3、退出redis,也会产生rdb文件

    备份就会自动生成一个dump.rdb

    如何恢复rdb文件

    1、只需要将rdb文件放在我们redis启动目录就可以了,redis启动时就会自动检查dump.rdb恢复其中的数据

    2、查看需要存在的位置,如果这个目录下存在dump.rdb文件,启动就会自动恢复其中的数据

    优点

    1、适合大规模的数据恢复

    2、对数据完整性要求不高

    缺点

    1、需要一定的时间间隔进行操作,如果redis意外宕机,这个最后一次修改的数据就没有了

    2、fork进程运行的时候需要占用一定的内存空间

    AOF(Append Only File)

    将我们的所有命令都记录下来,恢复的时候就把这个文件全部执行一遍

    什么是aof

    在这里插入图片描述

    以日志的形式来记录每个写操作,将redis执行过的所有指令记录下来(读操作不记录),只需追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据库,换言之,redis重启的话就根据日志wen’jian的内容将写指令从前到后执行一次以完成数据的恢复工作。

    AOF保存的是 appendonly.aof文件

    # Please check http://redis.io/topics/persistence for more information.
    
    appendonly no	#默认是不开启的,如果开启AOF改为yes即可
    
    # The name of the append only file (default: "appendonly.aof")
    
    appendfilename "appendonly.aof"	#默认文件名
    

    如果aof文件有错误,这时候redis是启动不起来的,我们需要修复aof文件

    redis提供了一个一个工具,redis-check-aop --fix

    在这里插入图片描述

    如果文件正常,重启就可以恢复了!

    在这里插入图片描述

    重写规则说明

    默认的是文件的无限追加,文件会越来越大

    # If you have latency problems turn this to "yes". Otherwise leave it as
    # "no" that is the safest pick from the point of view of durability.
    
    no-appendfsync-on-rewrite no
    
    # Automatic rewrite of the append only file.
    # Redis is able to automatically rewrite the log file implicitly calling
    # BGREWRITEAOF when the AOF log size grows by the specified percentage.
    #
    # This is how it works: Redis remembers the size of the AOF file after the
    # latest rewrite (if no rewrite has happened since the restart, the size of
    # the AOF at startup is used).
    #
    # This base size is compared to the current size. If the current size is
    # bigger than the specified percentage, the rewrite is triggered. Also
    # you need to specify a minimal size for the AOF file to be rewritten, this
    # is useful to avoid rewriting the AOF file even if the percentage increase
    # is reached but it is still pretty small.
    #
    # Specify a percentage of zero in order to disable the automatic AOF
    # rewrite feature.
    
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    
    
    #如果aof文件大于64mb,就会fork一个进程来将我们的文件进行重写
    

    aof优点缺点

    优点:

    1、每一次修改都同步,文件完整性会更好

    2、每秒同步一次,可能会丢失一秒数据

    3、从不同步,效率最高

    缺点:

    1、相对于数据文件来说,aof远大于rdb,修复的速度也比rdb慢

    2、aof运行效率比rdb慢所以redis默认配置是rdb持久化

    扩展

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P8Gf5eZQ-1627477765766)(C:\Users\51545\Desktop\MyPractice\笔记\redis\拓展1.PNG)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ptsud0u-1627477765767)(C:\Users\51545\Desktop\MyPractice\笔记\redis\拓展2.PNG)]

    Redis发布订阅

    redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息

    Redis客户端可以订阅任意数量的频道

    订阅/发布消息图

    在这里插入图片描述

    下图展示了频道channel1,以及订阅这是三个频道的三个客户端–client2、client5、和client1之间的关系

    在这里插入图片描述

    当有新消息通过publish命令发送给频道channel1时,这个消息就会被发送给订阅它的三个客户端

    在这里插入图片描述

    命令

    这些命令被广泛用于构建即时通信应用,比如聊天室(chatroom)和实时广播、实时提醒等

    在这里插入图片描述

    测试

    订阅端:

    127.0.0.1:6379> SUBSCRIBE lpx				#订阅一个频道	lpx
    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "lpx"
    3) (integer) 1
    #等待读取信息
    1) "message"	#消息
    2) "lpx"		#频道
    3) "hello,lpx"	#内容
    1) "message"
    2) "lpx"
    3) "hello,redis"
    

    发送端:

    127.0.0.1:6379> PUBLISH lpx "hello,lpx"		#发布者发布消息到频道
    (integer) 1
    127.0.0.1:6379> PUBLISH lpx "hello,redis"	#发布者发布消息到频道
    (integer) 1
    

    原理

    Redis是使用C实现的,通过分析Redis源码里的pubsub.c文件,了解发布和订阅的底层实现,其次加深对redis的理解。

    Redsi通过PUBLISH、SUBSCRIBE和PSUBSCRIBE等命令实现发布和订阅功能。

    通过SUBSCRIBE命令订阅某频道后,redis-server里维护了一个字典,字典的键就是一个个channel(频道),而字典的值则是一个链表,链表中保存了所有订阅这个channel的客户端。SUBSVRIBE命令的关键,就是将客户端添加到给定channel的订阅链表中。

    通过PUBLISH命令向订阅者发布消息,redis-server会使用给定的频道作为键,在它维护的channel字典中查找记录了订阅这个频道的所有客户端的链表,遍历这个链表,将消息发布给所有订阅者。

    PUB/SUB从字面上理解就是发布(publish)与订阅(subscrible),在Redis中,你可以设定对某一个key值进行消息发布及订阅,当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息。这一功能最明显的用法就是用作实时消息系统,比如普通的即时聊天,群聊等功能。

    使用场景

    1、实时消息系统

    2、实时聊天(频道作为聊天室,将信息回显给所有人即可)

    3、订阅、关注系统

    稍微复杂的场景就会使用消息中间件来实现例如:MQ

    Redis主从复制

    概念

    主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为主节点( master/leader ) ,后者称为从节点(slave/folIower ) ;数据的复制是单向的,只能由主节点到从节点。 Master 以写为主, Slave 以读为主。

    默认情况下,每台 Redis 服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。主从复制的作用主要包括:

    1 、数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。

    2 、故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。

    3 、负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写 R edis 数据时应用连接主节点,读 Redis 数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高 Redis服务器的并发量。

    4 、高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是 Redis 高可用的基础

    一般来说,要将 Redis 运用于工程项目中,只使用一台 Redis 是万万不能的,原因如下:

    1 、从结构上,单个 Redis 服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力较大;

    2 、从容量上,单个 R edis 服务器内存容量有限,就算一台 RediS 服务器内存容量为 256G ,也不能将所有内存用作 Redis 存储内存一般来说,单台 R edis 最大使用内存不应该超过 ZOG 。

    电商网站上的商品,一般都是一次上传,无数次浏览的,说专业点也就是”多读少写”。

    对于这种场景,我们可以使如下这种架构:

    在这里插入图片描述

    环境配置

    只配置从库,不配置主库!

    127.0.0.1:6379> info replication	#查看当前库的信息
    # Replication
    role:master			#角色
    connected_slaves:0	#从机数
    master_failover_state:no-failover
    master_replid:0fd5a5793a63b5dbe6e16fb29732bc6c7d536e2f
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:0
    second_repl_offset:-1
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    
    

    复制三个配置文件,然后修改对应信息

    1、端口

    2、pid名称

    3、log文件名称

    4、dump.rdb名字

    修改完成之后,启动三个redis服务器,可以通过进程信息查看

    在这里插入图片描述

    一主二从

    默认情况下,每台redis服务器都是主节点;我们一般情况下只需要配置从机就好了!

    类似认老大,一主(6379)二从(6380,6381)

    命令:SLAVEOF host port

    在这里插入图片描述

    在这里插入图片描述

    如果两个从机都配置完了,就是有两个从机的

    在这里插入图片描述

    真实的主从配置应该是在配置文件中配置,这样的话是永久的

    细节

    主机可以写。

    在这里插入图片描述

    从机不能写只能读!

    在这里插入图片描述

    主机中的所有信息和数据,都会自动被从机保存!

    测试:主机断开连接,从机依旧连接到主机的,但是没有写操作了,这个时候,主机如果重新连接了,从机依旧可以直接获取到主机写的信息!

    如果是使用命令行,来配置的主从,这个时候如果重启了,就会变回主机!只要变回了从机,立马就会从主机中获取值!

    复制原理

    Slave (从机)启动成功连接到 master 后会发送一个 sync 同步命令

    Master(主机) 接到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后, master将传送整个数据文件到 slave ,并完成一次完全同步。

    全量复制:而Slave 服务在接收到数据库文件数据后,将其存盘并加载到内存中。

    增量复制: Master 继续将新的所有收集到的修改命令依次传给 Slave ,完成同步

    但是只要是重新连接 m aster ,一次完全同步(全量复制)将被自动执行

    一带一路

    上一个主节点(M)连接下一个从节点(S)

    在这里插入图片描述

    这时候也可以完成主从复制

    如果没有了主机,这个时候可以选择一个作为主机,哨兵模式出现之前是手动!

    如果主机断开链接了,可以使用SLAVEOF no one选择某从机让其变为主机,其他节点可以手动连接到最新的主节点(手动),如果主机重新连接了,那就只能重新连接切换为原来的主节点。

    哨兵模式(自动选举模式)

    概述

    主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用.这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式. Redis 从 2 . 8 开始正式提供了 Sentinel (哨兵)架构来解决这个问题。

    谋朝篡位的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。

    哨兵模式是一种特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行.其原理是哨兵通过发送命令,等待 Redis服务器响应,从而监控运行的多个 Redis 实例。

    在这里插入图片描述

    这里的哨兵有两个作用:

    • 通过发送命令,让 Redis 服务器返回监控其运行状态,包括主服务器和从服务器.
    • 当哨兵监测到 master 宕机,会自动将slave 切换成 master ,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。

    然而一个哨兵进程对 R edis 服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

    在这里插入图片描述

    假设主服务器宕机,哨兵 1 先检测到随个结果,系统并不会马上进行 failove过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象称为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行 failover 「故障转移]操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。

    测试

    1、配置哨兵配置文件sentinel.conf

    #sentinel monitor 被监控的名称 host port 1
    sentinel monitor myredis 127.0.0.1 6379 1
    

    后面的数字1,代表主机挂了,slave投票看让谁接替成为主机,票数最多的就会成为主机

    2、启动哨兵

    在这里插入图片描述

    如果Master节点断开了,这个时候就会从从机中随机选择一个服务器作为主机(这里有一个投票算法)

    哨兵日志

    在这里插入图片描述

    哨兵模式

    如果原作为Master的主机重新连接了,只能归并到新Master主机下当作从机,这就是哨兵模式规则

    优点:

    1. 哨兵集群,基于主从复制,所有主从复制优点他都有
    2. 主从可以切换,故障可以转移,系统可用性会更好
    3. 哨兵模式就是主从模式升级,手动到自动,更加健壮

    缺点:

    1. Redis不好在线扩容,集群容量到达上限,在线扩容就十分麻烦
    2. 实现哨兵模式的配置其实是很麻烦的,里面有很多选择

    哨兵模式的全部配置

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    Redis缓存穿透和雪崩

    Redis 缓存的使用,极大的提升了应用程序的性能和效率,特别是数据查询方面。但同时,它也带来了一些问题。其中,最要害的问题,就是数据的一致性问题,从严格意义上讲,这个问题无解。如果对数据的一致性要求很高,那么就不能使用缓存。另外的一些典型问题就是,缓存穿透、缓存雪崩和缓存击穿。目前,业界也都有比较流行的解决方案。

    缓存穿透

    概念

    缓存穿透的概念很简单,用户想要查询一个数据,发现 redis内存数据库没有,也就是缓存没有命中,于是向持久层数据库查询。发现也没有,于是本次查询失败。当用户很多的时候,缓存都没有命中,于是都去请求了持久层数据库。这会给持久层数据库造成很大的压力,这时候就相当于出现了缓存穿透。

    解决方案

    布隆过滤器

    布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力。

    在这里插入图片描述

    缓存空对象

    当存储层不命中,即返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源;

    在这里插入图片描述

    但是这种方法会存在两个问题:

    1、如果空值能够被缓存起来,这就意会着缓存需要更多的空间存储更多的键,因为这当中可能会有很多的空值的键;

    2、即使设置了过期时间,还是会存在缓存层和存储层的数据会有一段时间窗口的不一致,这对于需要保持一致性的业务会有影响。

    缓存击穿

    概述

    这里需要注意和缓存穿透的区别,缓存击穿,是指一个 key 非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key 在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

    当某个 key 在过期的瞬间,有大量的请求并发访问,这类数据一般是热点数据,由于缓存过期,会同时访问数据库来查询最新数据,并且回写缓存,会导使数据库瞬间压力过大.

    解决方案

    设置热点数据永不过期

    从缓存层面看,mei’you’she’zhi过期时间,所以不会出现热点key过期后产生的问题。

    加互斥锁

    分布式锁:使用分布式锁,保证对于每个ket同时只有一个线程去查询后端服务。其他线程没有获得分布式锁的权限,因此只需要等待即可。这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大。

    缓存雪崩

    概念

    缓存雪崩,是指在某一个时间段,缓存集中过期失效。 Redis 宕机!

    产生雪崩的原因之一,比如在写本文的时候,马上就要到双十二零点,很快就会迎来一波抢购,这波商品时间比较集中的放入了缓存,假设缓存一个小时。那么到了凌晨一点钟的时候,这批商品的缓存就都过期了。而对这批商品的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰.于是所有的请求都会达到存储层,存储层的调用量会暴增,造成存储层也会挂掉的情况。

    在这里插入图片描述

    解决方案

    redis 高可用

    这个思想的含义是,既然 redis 有可能挂掉,那我多增设几台 redis ,这样一台挂掉之后其他的还可以继续工作,其实就是搭建的集群。

    限流降级

    这个解决方案的思想是,在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个 key 只允许一个线程查询数据和写缓存,其他线程等待。

    数据预热

    数据加热的含义就是在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。在即将发生大并发访问前手动触发加载缓存不同的 key ,设置不同的过期时间,让缓存失效的时间点尽量均匀。

    特别鸣谢:@狂神说JAVA->哔哩哔哩

    展开全文
  • Uber Rides Android SDK(测试版) 官方Android SDK支持: 乘车请求按钮 骑行请求深层链接 优步认证 REST API 此SDK至少应与Android SDK 15配合使用。 在你开始之前 在使用此SDK之前,请在上注册您的应用程序。 ...
  • Rides

    2015-06-22 18:53:00
    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace RedisCall{ using ServiceStack.Redis; class Program { s...

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace RedisCall
    {
    using ServiceStack.Redis;

    class Program
    {
    static void Main(string[] args)
    {
    //开始调用
    //1.0 确定redis服务器的ip(127.0.0.1)+port (默认6379)
    //2.0 实例化redis的客户端实例
    using (var client = RedisClientFactory.Instance.CreateRedisClient("127.0.0.1", 6379))
    {
    //3.0 利用Set存储数据:特点:如果key不存在,则创建,否则跟新其数据(相同的键后面的会覆盖前面的)
    client.Set<string>("name1", "{name:ivan}");
    client.Set<string>("name1", "{name:ivan11111111}");

    Console.WriteLine(client.Get<string>("name1"));

    //4.0 List
    client.AddItemToList("age1", "29");
    client.AddItemToList("age1", "30");
    client.AddItemToList("age1", "29");

    List<string> list = client.GetAllItemsFromList("age1");
    list.ForEach(c => Console.WriteLine(c));

    //5.0 Set 用于数据消重
    client.AddItemToSet("蜀国", "刘备");
    client.AddItemToSet("蜀国", "张飞");
    client.AddItemToSet("蜀国", "刘备");

    client.GetAllItemsFromSet("蜀国").ToList().ForEach(c => Console.WriteLine(c));

    //6.0 实现队列操作(先进先出)
    //client.EnqueueItemOnList("魏国", "老王");
    //client.EnqueueItemOnList("魏国", "曹操");
    //client.EnqueueItemOnList("魏国", "张辽");

    int count = client.GetListCount("魏国");
    for (int i = 0; i < count; i++)
    {
    //将数据出队列以后,同时移除该数据
    Console.WriteLine(client.DequeueItemFromList("魏国"));
    }

    }

    Console.ReadKey();
    }

    }
    }

     

    转载于:https://www.cnblogs.com/cdaq/p/4593672.html

    展开全文
  • Redis 雪崩:  雪崩就是指缓存中大批量热点数据过期后系统涌入大量查询请求,因为大部分数据在Redis层已经失效,请求渗透到数据库层,大批量请求犹如洪水一般涌入,引起数据库压力造成查询堵塞甚至宕机。...
  • Rides:基本操作与原理

    千次阅读 2019-02-18 22:40:59
    目录 【redis是什么】 【谁在使用redis】 【使用redis客户端】 【redis数据结构】 【 strings】 【lists】 【集合set】 【有序集合】 【哈希】 ...redis是一个开源的、使用C语言编写的、支持网...
  • 分布式环境下多个操作以原子的方式执行 单体操作可以加锁synchronized{ } 如果是分布式的环境 前端niginx部署多个端口,会有bug redis中文手册api setnx 将key的值设为values,当key不存在时,如果给定的key已经存在...
  • rides-frontend-源码

    2021-03-22 07:41:44
    该项目是通过引导的。 可用脚本 在项目目录中,可以运行: npm start 在开发模式下运行该应用程序。打开在浏览器中查看它。 如果您进行编辑,则页面将重新加载。您还将在控制台中看到任何棉绒错误。...
  • Uber Rides Android SDK (beta) Official Android SDK to support: Ride Request Button Ride Request Deeplinks Uber Authentication REST APIs At a minimum, this SDK is designed to work with Android SDK ...
  • Hope Rides Alone-crx插件

    2021-03-14 00:27:20
    用rad 80的主屏幕替换新的选项卡屏幕。 简单的新标签更换,带有80年代的复古主题,待办事项列表生成器和本地温度。 支持语言:English
  • Rides持久化机制

    2020-07-20 22:40:00
    Rides的持久化及其原理 一、 持久化介绍 1.什么是持久化 利用永久性存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持久化。 2.怎样保证持久化 Redis 为了保证效率,数据缓存在了内存中,...
  • uber_Rides_Weekly-源码

    2021-04-05 14:16:45
    uber_Rides_Weekly
  • pool_rides 一个新的Flutter项目。 作者 毛里西奥·杜兰@mauduran 埃德加·麦地那(Edgar Medina)@ipanchomx 入门 该项目是Flutter应用程序的起点。 如果这是您的第一个Flutter项目,那么有一些资源可以帮助您入门...
  • 安装Rides

    2020-11-29 12:46:53
    文章目录前言一、Redis是什么?二、安装Redis1.把安装文件上传到liunx系统上2.安装redis总结 前言 在Web应用发展的初期,那时关系型数据库受到了较为广泛的关注和应用,原因是因为那时候Web站点基本上访问和并发不...
  • stackery-wild-rides-源码

    2021-03-10 02:08:45
    堆栈空白SAM模板 这是无服务器AWS Lambda应用程序的示例模板。 这是文件的概述: . ├── deployHooks/ <-- Directory for storing deployment hooks ├── .gitignore <-- Gitignore for Stackery ...
  • 如果你敲入命令 dmsg | grep rocket 输出了类似这样的 xen_netfront: xennet: skb rides the rocket: 19 slots skb乘火箭飞走了??为啥是19呢? 这里有位大侠使用内核调试工具,我是看不太懂:...
  • Rides 3.0.0 中文文档

    2017-03-24 21:31:00
    Rides 3.0.0 API construct 语法:__construct() 定义:构造方法 $redis = new Redis(); connect 语法:connect( $host, $port = 6379, $timeout = 0.0, $retry_interval)...
  • 的士 高峰时段乘车时间
  • Rides入门

    千次阅读 2018-10-26 22:32:41
    Redis配置: Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程 daemonize no 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定 ...
  • 内容简介,父类以及子类结构,重点在于通过@Service实现类,判断类型来new出不同的缓存实现类 首先要写一个缓存接口CacheService,来统一规定缓存的必要操作. public interface CacheService { ...
  • 消防骑克隆 消防游戏克隆游戏

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,443
精华内容 1,377
关键字:

rides