上杭县城乡规划建设局网站网页设计论文

当前位置: 首页 > news >正文

上杭县城乡规划建设局网站,网页设计论文,网页游戏排行力荐新壹玩,wordpress主题是用什么开发出来的一、redis pipeline 1.1、客户端同时发出多个请求#xff0c;redis服务端依次执行#xff0c;最后一次性返回结果。#xff08;节约往返时间#xff09; 之前是一请求一回应同步模式#xff0c;CS之间往返次数较多#xff0c;使用pipeline可以减少往返次数。
使用pip…一、redis pipeline 1.1、客户端同时发出多个请求redis服务端依次执行最后一次性返回结果。节约往返时间 之前是一请求一回应同步模式CS之间往返次数较多使用pipeline可以减少往返次数。
使用pipeline之后提前告诉服务端我要发几条命令服务端一次性执行完之后返回结果。
1.2、redis 事务 是用户定义的将多条命令打包在服务端执行要么全部执行要么全部不执行。 相关命令 1、开启事务multi2、检测key的变动在未来如果有其他连接修改了该key则取消事务WATCH key3、EXEC 提交事务4、DISCARD 取消事务 事务有什么用 以AB两个客户端为例连接redis服务器同时操作同一个key如果不使用事务那么结果就可能被修改
A客户端想要一个k1为100的值但B客户端想要一个k1为200的值此时A再使用k1时发现值已经发生了变化并不是A所想要的。 使用事务之后
分别执行提交事务两次其中一个成功返回OK另一个返回nil,这是因为使用watch命令在提交事务之前如果其他客户端修改了key的值那么此次事务就会取消。实质上redis采用的是乐观锁不同于传统数据库MySQL并不是悲观锁。 1.3 ACID特性 原子性Atomocity事务是一个不可分割的工作单位事务中的操作要么全部成功要么全部失败。一致性Consistency事务应确保数据从一个正确的状态转移到另一个正确的状态。注意此处特指数据库层面的正确性而非应用层面的正确性–逻辑上的一致性。隔离性Isolation事务的执行不应该被其他事务干扰redis 是单线程执行天然具备隔离性。持久性Durability一旦事务提交则其所做的修改将会永远保存到数据库(磁盘)中redis 只有在 aof 持久化策略的时候并且需要在 appendfsyncalways 才具备持久性 二、使用Lua与redis进行互动 实际开发中使用lua来实现事务保证原子性很少使用上面这些命令 2.1、为什么使用Lua redis底层是用C语言写的而Lua是用C语言写的两者可以互相调用。redis中加载了一个lua 虚拟机用来执行redis lua 脚本。Lua在执行的时候具备原子性减少tcp网络流量的浪费将多个命令封装成一个脚本执行减少网络往返次数。复用性灵活性热更新 2.2、使用Lua eval local key KEYS[1]; local value redis.call(get, key); return value 1 k1这是简单的lua脚本KEYS[1]是redis传过来的参数如果脚本代码过多这样就不方便。 2.3、加载Lua脚本

从文件中读取 lua脚本内容

cat test.lua | redis-cli script load –pipe #获取脚本的 sha1 散列值推荐使用 redis-cli -a pwd script load $(cat test.lua)# 检查脚本缓存中是否有该 sha1 散列值的lua脚本 script exists b8059ba43af6ffe8bed3db65bac35d452f8115d8# 清除所有脚本缓存 script flush# 如果当前脚本运行时间过长(死循环)可以通过 script kill 杀死当前运行的脚本 script kill优化lua代码减少TCP流量的浪费 – 简单的加法运算 local key KEYS[1]; local increment tonumber(ARGV[1] or 1); local current tonumber(redis.call(get, key) or 0);if not increment or not current thenreturn nil; end;local new_value current increment;redis.call(set, key, new_value); return new_value;那lua是否具备一致性 不具有一致性 set k1 100 lpush k1 1 get k1 #代码就只执行到第一句第二句出错就不执行了。(以redis命令为例lua同理)2.4、小结 1、使用lua脚本可以保证原子性。2、减少网络往返次数。3、复用性好。4、灵活性高。5、热更新。6、lua具备原子性但不具备一致性。 三、服务器与Redis进行交互 3.1、前置条件生成库文件 cd redis-xxx/deps/hiredis make make install

使用cmake

mkdir build cd build cmake .. make install3.1、同步连接 作者给出hiredis文件中已经实现已经留出了接口可以直接使用。 //连接redis服务器 redisContext *redisConnectWithOptions(const redisOptions *options); redisContext *redisConnect(const char *ip, int port); redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv); redisContext *redisConnectNonBlock(const char *ip, int port); redisContext *redisConnectBindNonBlock(const char *ip, int port,const char *source_addr); redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,const char *source_addr); redisContext *redisConnectUnix(const char *path); redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv); redisContext *redisConnectUnixNonBlock(const char *path); redisContext *redisConnectFd(redisFD fd);//执行redis命令 void *redisvCommand(redisContext *c, const char *format, va_list ap); void *redisCommand(redisContext *c, const char *format, …); void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);//断开连接 void freeReplyObject(void *reply); void redisFree(redisContext *c);unsigned int j, isunix 0;redisContext *c;redisReply *reply;const char *redis_password 123456;// 定义连接超时时间struct timeval timeout { 1, 500000 }; // 1.5 秒// 初始化连接选项redisOptions options;memset(options, 0, sizeof(redisOptions));// 设置 Redis 服务器的主机名和端口const char *hostname 127.0.0.1;const int port 6379;REDIS_OPTIONS_SET_TCP(options, hostname, port);// 设置连接超时和命令超时options.connect_timeout timeout;options.command_timeout timeout;// 尝试建立连接c redisConnectWithOptions(options);if (c NULL || c-err) {if © {printf(Connection error: %s\n, c-errstr);redisFree©;} else {printf(Connection error: can not allocate redis context\n);}exit(1);}//认证密码如果有密码的话需要先认证一下没有密码那就注释掉这行代码。reply redisCommand(c, AUTH %s, redis_password);if (reply-type REDIS_REPLY_ERROR) {printf(Redis认证失败\n);}else{printf(Redis认证成功\n);}// 执行 Redis 命令int roleid 10086;// 检查键是否存在reply redisCommand(c, EXISTS role:%d, roleid);if (reply NULL) {printf(Command error: %s\n, c-errstr);redisFree©;exit(1);}if (reply-type REDIS_REPLY_INTEGER reply-integer 0) {printf(Key does not exist.\n);freeReplyObject(reply);} else {freeReplyObject(reply);// 执行 hgetall 命令reply redisCommand(c, hgetall role:%d, roleid);if (reply NULL) {printf(Command error: %s\n, c-errstr);redisFree©;exit(1);}// 处理命令回复if (reply-type ! REDIS_REPLY_ARRAY) {if (reply-type REDIS_REPLY_NIL) {printf(Key does not exist or hash is empty.\n);} else {printf(Reply error: expected array, got %d\n, reply-type);}} else {// 处理数组回复的逻辑printf(Reply: number of elements%lu\n, reply-elements);for (size_t i 0; i reply-elements; i 2) {printf(\t%s: %s\n, reply-element[i]-str, reply-element[i 1]-str);}}// 释放回复对象freeReplyObject(reply);}// 释放连接上下文redisFree©;因为此时数据库是空的所以没有查到数据。 3.2、异步连接基于当前的网络模块-recator实现驱动 核心思路 reactor是一种基于事件驱动的模式所以在redis的异步连接中我们也需要使用事件驱动的方式来处理网络IO操作。需要做的就是构建事件对象redis事件对象reactor事件对象适配事件控制复用reactor事件控制 具体操作 hiredis已经提供了事件操作的接口我们只需要适配这些事件操作的接口
redis_event_t re; re (redis_event_t)hi_malloc(sizeof(*re)); //这些是 hiredis 要求你实现的“注册函数”。每当 Redis 需要监听某个 FD 的读/写事件就会调用这些函数 ac-ev.addRead redisAddRead; ac-ev.delRead redisDelRead; ac-ev.addRead redisAddWrite; ac-ev.delWrite redisDelWrite; ac-ev.cleanup redisCleanup;//清理函数必不可少 ac-ev.data re;核心代码 /在hiredis/async.h中作者提供了许多异步执行的接口/ int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap); int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, …); int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char cmd, size_t len); / */ // 1. 创建 event loop R create_reactor();// 2. 连接redis redisAsyncContext c redisAsyncConnect(127.0.0.1, 6379); if (c-err) {/ Let *c leak for now… */redisAsyncFree©;printf(Error: %s\n, c-errstr);return 1; } // 3. 将 redisAsyncContext 附加到 event loop 上主要是注册回调函数填写相关事件 redisAttach(R, c);// 4.设置连接成功/断开回调函数 redisAsyncSetConnectCallback(c, connectCallback); redisAsyncSetDisconnectCallback(c, disconnectCallback);eventloop®;release_reactor®;四、总结 redis事务是为了改变之前一请求一回应的模式让多个命令可以并发执行并且要么全部执行成功要么全部执行失败 redis底层内置Lua虚拟机使用Lua脚本语言亲和性会更高 使用lua脚本可以保证原子性但不具备一致性 Lua脚本的优势减少网络往返次数复用性好灵活性高热更新等 服务器与redis进行交互可以使用同步和异步两种方式同步方式简单直接但效率较低而异步方式则可以充分利用网络IO的并发性提高性能。 同步连接方案采用阻塞 io 来实现优点是代码书写是同步的业务逻辑没有割裂缺点是阻塞当前线程直至 redis 返回结果通常用多个线程来实现线程池来解决效率问题 异步连接方案采用非阻塞 io 来实现优点是没有阻塞当前线程
五、问题 5.1、什么情况下探讨事务 多条命令并发执行什么情况下探讨原子操作操作 多核情况下乐观锁和悲观锁的区别 乐观锁假定不会发生并发冲突只在提交操作时检查是否违反数据完整性。在提交事务前不锁定而是在提交事务时检查访问权限。 悲观锁假定会发生并发冲突屏蔽一切可能违反数据完整性的操作。在访问资源之前就先将其锁定。 Code Ovoice·Github