thecloudlesssky / nhibernate.caches.redis Goto Github PK
View Code? Open in Web Editor NEWAn NHibernate caching provider for Redis.
License: MIT License
An NHibernate caching provider for Redis.
License: MIT License
I have read the source, and I'm confused that why to store Generation and Keyset?
1.Is there any condition to make serverGeneration and CacheNamespace.GetGeneration inconsistent?
2.When put a NH entity to redis, the put method also put it's cacheKey to a redis set, but it is never using again. Why?
Hi there,
I have a question about caching tables. If I don't specify anything and use default options for Redis, I belive it caches the whole NHibernate Queries. What is the best way cache specific table but not all?
Our situation:
Table "A" has ~100.000.000 records, and has rather specific load pattern - if a row is queried then it is likely it will be queried again few thousand times over next few minutes.
Around 5000 different rows are queried every minute (distribution is near random).
After a few minutes given row might not be accessed again for days.
A logical setup would be to set CacheRegion absolute expiry to ~ 5 minutes and keep only "hot" rows in cache (~ 5 * 5.000 = ~ 25.000 rows in cache).
Since SetOfActiveKeysKey items have no expiry, it will build up over time (items are removed from cache via expiry, but :keys records are kept). With our load pattern, this leads to having 10+m records in :keys set, while having ~25.000 items cached. I'm quite certain this has negative effect on lookup speed (not tested though), and certain about memory consumption - purging the :keys will result in few GB of freed memory
At the moment we use scheduled cleanup as a workaround, but this seems like a hack and shouldn't be part of this project? At the same time I can't figure out how to address this issue cleanly - considering current cache architecture.
(The hack we use is to run a schedule every minute that does full SCAN (preferably on slave), finds :keys entries, does SSCAN on each entry, finds (in memory) obsolete entries and deletes them in batches)
Nhibernate 5 chacged ICache interface adding async methods Nhibernate.Caches.Redis fails with it.
You'll get the following error trying to use this cache provider
System.TypeLoadException: Method 'GetAsync' in type 'NHibernate.Caches.Redis.RedisCache' from assembly 'NHibernate.Caches.Redis, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
Hi,
We are currently working on splitting our database into multiple 'shards'. Each shard will have it's own database connection/session factory and the next step is to configure each shard to have a separate redis store.
What I'd actually like to do is to to just use the region name to isolate the caches for each session factory.
Would it be possible to use the NHibernate redis cache in this way? To initialise the cache with different options for each session factory? The fact that RedisCacheProvider.SetOptions
is static is giving me some doubts on whether this is achievable.
Would be awesome with a implementation with https://github.com/StackExchange/StackExchange.Redis as that provider doesnt have any limitations as ServiceStack.Redis have.
Any plans on that?
Hi
Is there plan to build NHibernate.Caches.Redis.2.0.0 with new nhibernate 4.
Thx
Regards
I'm just in the process of upgrading our NHibernate.Caches.Redis from quite an old version that used the ServiceStack.Redis client.
I'm reading through the README and it mentions that it's possible to switch serialisers to, for example, the NhCacheJsonSerialiser.
I was just wondering if you could explain the benefits/drawbacks of doing so? Would it be more performant?
I added this nuget 3.0 beta 4 to an app and I get the error System.Object' to type 'System.Byte[]. Any ideas?
Hi!
Trying to set up NH Redis Cache, but I get these errors when compiling:
The type 'ServiceStack.Redis.IRedisNativeClient' is defined in an assembly that is not referenced. You must add a reference to assembly 'ServiceStack.Interfaces, Version=3.9.9.0, Culture=neutral, PublicKeyToken=null'.
The type 'ServiceStack.Redis.IRedisClientsManager' is defined in an assembly that is not referenced. You must add a reference to assembly 'ServiceStack.Interfaces, Version=3.9.9.0, Culture=neutral, PublicKeyToken=null'.
The type 'ServiceStack.Redis.IRedisClientCacheManager' is defined in an assembly that is not referenced. You must add a reference to assembly 'ServiceStack.Interfaces, Version=3.9.9.0, Culture=neutral, PublicKeyToken=null'.
The type 'ServiceStack.Redis.IRedisClient' is defined in an assembly that is not referenced. You must add a reference to assembly 'ServiceStack.Interfaces, Version=3.9.9.0, Culture=neutral, PublicKeyToken=null'.
Problem is, the ServiceStack included here is v4.
This is with a fresh installation of NHibernate.Caches.Redis.
Weird thing is, in the editor everything looks good.
I've been evaluating possibility of usage of this cache provider, and one thing I've done while fooling around with it was to execute FlushDb through Redis console (my idea was to test situation where Redis data gets lost for some reason).
As a result my IIS freezed completely, it turned out that RedisCache's method ExecuteEnsureGeneration is causing an infinite loop.
while (serverGeneration != CacheNamespace.GetGeneration())
{
CacheNamespace.SetGeneration(serverGeneration);
transaction.Replay();
}
Problem is - serverGeneration after FlushDb is 0 and is different from CacheNamespace.GetGeneration(). Unfortunately executing CacheNamespace.SetGeneration(0) is not changing CacheNamespace generation to 0 because it does not allow setting generation to a value that is less than current generation.
Than transaction is replayed and because CacheNamespace generation has not changed we got infinite loop.
I'm happy to create patch for it, I would like to get some comments though on the problem before I dig into it.
Hi, we're getting a lot of timeouts when acquiring locks. i.e. errors like
Acquiring lock for 'XXX' exceeded timeout '00:00:30'.
Do you have any tips or advice for trouble shooting why we might be timing out when acquiring locks and / or best practices for trying to minimise lock timeouts?
Dear Cloudless Sky,
I am trying to use NHibernate.Caches.Redis in my project. Time taken to retrieve data from cache is more than normal DB call.
Our scenario is as : Suppose we have 200 entries in DB. We triggered select query. NHibernate.Caches.Redis loads each record into its cache. When the same select query is fired again then NHibernate.Caches.Redis loads the record from cache . But since serialization/deserialization of NHibernate.Caches.Redis is taking almost ~1ms for each and every record. Therefore the time taken in second select query from cache is almost 180 ms which is more than direct DB fetch because direct DB fetch is taking only 15 ms.
Please suggest a workaround for this problem.
Hi,
without a defined pattern my code catch this error:
Timeout performing SET NHibernate-Cache:Medium:ACompany.FMS.Data.Objects.OperationStock.OilStockOperationBalance#77110:lock, inst: 0, mgr: ProcessReadQueue, err: never, queue: 0, qu: 0, qs: 0, qc: 0, wr: 0, wq: 0, in: 0, ar: 1, clientName: MIL-S-613, IOCP: (Busy=0,Free=1000,Min=24,Max=1000), WORKER: (Busy=0,Free=32767,Min=24,Max=32767), Local-CPU: 0% (Please take a look at this article for some common client-side issues that can cause timeouts: https://github.com/StackExchange/StackExchange.Redis/tree/master/Docs/Timeouts.md)
I've read the suggested page but I didn't fond anything that helps. Can you point me in the right way or help to solve, many thanks
I'm getting an exception after restarting Redis:
[SocketException (0x2746): An existing connection was forcibly closed by the remote host]
System.Net.Sockets.Socket.Send(IList`1 buffers, SocketFlags socketFlags) +3094587
ServiceStack.Redis.RedisNativeClient.FlushSendBuffer() +118
ServiceStack.Redis.RedisTransaction.Commit() +553
I'm using PooledRedisClientManager, using BasicRedisClientManager helps a little (got this exception on the first request only, subsequent were fine).
I believe that this provider should be more robust and handle exceptions like this by simply returning nothing from the cache so NHibernate can still operate and execute regular query.
Any thoughts ?
Hi,
I am having issues getting keys from a cluster node. The below is the exception i am getting.
Any ideas ???
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> NHibernate.Caches.Redis.RedisCacheException: Failed to get item from cache. See inner exception. ---> StackExchange.Redis.RedisServerException: ERR Error running script (call to f_cc7714ec6575efa50255574fa61586c11611ab0e): @user_script:2: @user_script: 2: Lua script attempted to access a non local key in a cluster node
at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor1 processor, ServerEndPoint server) in C:\TeamCity\buildAgent\work\3ae0647004edff78\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs:line 2052 at StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor
1 processor, ServerEndPoint server) in C:\TeamCity\buildAgent\work\3ae0647004edff78\StackExchange.Redis\StackExchange\Redis\RedisBase.cs:line 81
at StackExchange.Redis.RedisDatabase.ScriptEvaluate(String script, RedisKey[] keys, RedisValue[] values, CommandFlags flags) in C:\TeamCity\buildAgent\work\3ae0647004edff78\StackExchange.Redis\StackExchange\Redis\RedisDatabase.cs:line 891
at StackExchange.Redis.RedisDatabase.ScriptEvaluate(LuaScript script, Object parameters, CommandFlags flags) in C:\TeamCity\buildAgent\work\3ae0647004edff78\StackExchange.Redis\StackExchange\Redis\RedisDatabase.cs:line 902
at NHibernate.Caches.Redis.RedisCache.Get(Object key)
--- End of inner exception stack trace ---
at NHibernate.Caches.Redis.RedisCache.Get(Object key)
at NHibernate.Cache.ReadOnlyCache.Get(CacheKey key, Int64 timestamp)
at NHibernate.Event.Default.DefaultLoadEventListener.LoadFromSecondLevelCache(LoadEvent event, IEntityPersister persister, LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.DoLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType)
at NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType)
at NHibernate.Impl.SessionImpl.ImmediateLoad(String entityName, Object id)
at NHibernate.Proxy.AbstractLazyInitializer.Initialize()
at NHibernate.Proxy.DefaultLazyInitializer.Intercept(InvocationInfo info)
at ApplicationInstanceProxy.get_Hierarchy()
at Tio.Web.Express.InstanceSetup.SetDataTokensForInstance(String instanceName, ApplicationInstance instance) in D:\dev\Web\Tio.Web.Express\Tio.Web.Express\App_Start\InstanceSetup.cs:line 96
at Tio.Web.Express.InstanceSetup.Initialize() in D:\dev\Web\Tio.Web.Express\Tio.Web.Express\App_Start\InstanceSetup.cs:line 75
at Tio.Web.Express.InstanceSetup.Configure() in D:\dev\Web\Tio.Web.Express\Tio.Web.Express\App_Start\InstanceSetup.cs:line 33
at Tio.Web.Express.MvcApplication.Application_BeginRequest() in D:\dev\Web\Tio.Web.Express\Tio.Web.Express\Global.asax.cs:line 70
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at System.Web.Util.ArglessEventHandlerProxy.Callback(Object sender, EventArgs e)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
It's impossible to configure NH with the following code, if NHibernate.Caches.Redis assembly is simply add via Nuget
var clientManager = new PooledRedisClientManager("localhost:6379"); RedisCacheProvider.SetClientManager(clientManager);
Build failed, ServiceStack.Interfaces 3.9 required.
Hi,
Is there reason you are using "NHibernate" version="3.2.0.4000" targetFramework="net40" ?
Regards
We already use a distributed lock, but this would work where there is more than one Redis instance:
I notice the default LockTimeout value is 30 seconds. Is this the time it will attempt to retrieve a value from Redis before failing? Most of my requests take less than 25ms so would it be safe to make this something like 1 or 2 seconds? The reason being that I am using Redis on Azure and it periodically has connection issues which I would prefer to fail quickly on rather than wait.
I am using NHibernate.Cache.Redis for my project in .NET Core 2.2 and faced this exception.
Please give me a help!
Thanks
System.TypeLoadException: Method 'GetAsync' in type 'NHibernate.Caches.Redis.RedisCache' from assembly 'NHibernate.Caches.Redis, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
And another question is does NHibernate.Caches.Redis support .NET core?
I have configure second level cache for NHibernate to use redis cache in my project. But i just face The connection multiplexer can only be configured once
exception. Can you show me the reason?
Thanks
var connectionMultiplexer = ConnectionMultiplexer.Connect("localhost:6379,allowAdmin=true");
connectionMultiplexer.GetServer("localhost", 6379).FlushAllDatabases();
RedisCacheProvider.SetConnectionMultiplexer(connectionMultiplexer);
RedisCacheProvider.SetOptions(new RedisCacheProviderOptions()
{
Serializer = new NetDataContractCacheSerializer(),
CacheConfigurations = new[]
{
new RedisCacheConfiguration("NHibernate.Cache.StandardQueryCache")
{
Expiration = TimeSpan.FromSeconds(9)
}
}
});
cfg.DataBaseIntegration(x =>
{
x.ConnectionProvider<DriverConnectionProvider>();
x.ConnectionStringName = GlobalConstant.DefaultConnectionString;
x.LogSqlInConsole = true;
x.LogFormattedSql = true;
switch (ServerHelper.ServerType)
{
case GlobalConstant.PostgresServer:
x.Dialect<PostGis20Dialect>();
x.Driver<NpgsqlDriver>();
//<property name="hbm2ddl.keywords">none</property>
break;
case GlobalConstant.MySqlServer:
x.Dialect<MySQL57SpatialDialect>();
x.Driver<MySqlDataDriver>();
break;
default:
x.Dialect<MsSql2012GeometryDialect>();
x.Driver<SqlClientDriver>();
break;
}
});
cfg.SetProperty("current_session_context_class", "web");
cfg.SetProperty("cache.provider_class", "NHibernate.Caches.Redis.RedisCacheProvider, NHibernate.Caches.Redis"); //cfg.SetProperty("cache.provider_class", "NHibernate.Caches.SysCache.SysCacheProvider,NHibernate.Caches.SysCache");
cfg.SetProperty("cache.use_query_cache", "true");
cfg.SetProperty("cache.use_second_level_cache", "true");
cfg.AddAssembly(Assembly.GetExecutingAssembly());
I got "Could not load file or assembly 'NHibernate, Version=3.3.1.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference."
Environment:
VS2015
.net 4.5.1
"NHibernate.Caches.Redis": "2.0.0",
"NHibernate": "4.0.3.4000",
"StackExchange.Redis": "1.1.608",
If I add this below into web.config
I got different error: "Could not load file or assembly 'NHibernate' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference."
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.